mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[vizio] Improve handling of TV's self-signed certificate (#14429)
Signed-off-by: Michael Lobstein <michael.lobstein@gmail.com>
This commit is contained in:
parent
8c56a0f0b3
commit
7c20a4804a
@ -134,7 +134,7 @@ If an app that is in the JSON database fails to start when selected, try adjusti
|
||||
A current list of `APP_ID`'s can be found at http://hometest.buddytv.netdna-cdn.com/appservice/vizio_apps_prod.json
|
||||
and `NAME_SPACE` & `MESSAGE` values needed can be found at http://hometest.buddytv.netdna-cdn.com/appservice/app_availability_prod.json
|
||||
|
||||
If there is an error in the user supplied `appListJson`, the thing will fail to start and display a CONFIGURATION_PENDING message.
|
||||
If there is an error in the user supplied `appListJson`, the thing will fail to start and display a CONFIGURATION_ERROR message.
|
||||
If all text in `appListJson` is removed (set to null) and the thing configuration saved, the binding will restore `appListJson` from the binding's JSON db.
|
||||
|
||||
## Full Example
|
||||
|
@ -16,7 +16,6 @@ import static org.openhab.binding.vizio.internal.VizioBindingConstants.SUPPORTED
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.openhab.binding.vizio.internal.appdb.VizioAppDbService;
|
||||
import org.openhab.binding.vizio.internal.handler.VizioHandler;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
@ -39,7 +38,7 @@ import org.osgi.service.component.annotations.Reference;
|
||||
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.vizio")
|
||||
public class VizioHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
private final HttpClientFactory httpClientFactory;
|
||||
private final VizioStateDescriptionOptionProvider stateDescriptionProvider;
|
||||
private final String vizioAppsJson;
|
||||
|
||||
@ -47,7 +46,7 @@ public class VizioHandlerFactory extends BaseThingHandlerFactory {
|
||||
public VizioHandlerFactory(final @Reference HttpClientFactory httpClientFactory,
|
||||
final @Reference VizioStateDescriptionOptionProvider provider,
|
||||
final @Reference VizioAppDbService vizioAppDbService) {
|
||||
this.httpClient = httpClientFactory.getCommonHttpClient();
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
this.stateDescriptionProvider = provider;
|
||||
this.vizioAppsJson = vizioAppDbService.getVizioAppsJson();
|
||||
}
|
||||
@ -62,7 +61,7 @@ public class VizioHandlerFactory extends BaseThingHandlerFactory {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID)) {
|
||||
VizioHandler handler = new VizioHandler(thing, httpClient, stateDescriptionProvider, vizioAppsJson);
|
||||
VizioHandler handler = new VizioHandler(thing, httpClientFactory, stateDescriptionProvider, vizioAppsJson);
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ public class VizioCommunicator {
|
||||
* @throws VizioException
|
||||
*
|
||||
*/
|
||||
public PairingStart starPairing(String deviceName, int deviceId) throws VizioException {
|
||||
public PairingStart startPairing(String deviceName, int deviceId) throws VizioException {
|
||||
return fromJson(
|
||||
putCommand(urlStartPairing,
|
||||
String.format("{ \"DEVICE_NAME\": \"%s\", \"DEVICE_ID\": \"%d\" }", deviceName, deviceId)),
|
||||
|
@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2023 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.vizio.internal.communication;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import javax.net.ssl.X509ExtendedTrustManager;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.io.net.http.PEMTrustManager;
|
||||
import org.openhab.core.io.net.http.TlsTrustManagerProvider;
|
||||
import org.openhab.core.io.net.http.TrustAllTrustManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Provides a {@link PEMTrustManager} to allow secure connections to a Vizio TV that uses self signed
|
||||
* certificates.
|
||||
*
|
||||
* @author Christoph Weitkamp - Initial Contribution
|
||||
* @author Michael Lobstein - Adapted for Vizio binding
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class VizioTlsTrustManagerProvider implements TlsTrustManagerProvider {
|
||||
private final String hostname;
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(VizioTlsTrustManagerProvider.class);
|
||||
|
||||
public VizioTlsTrustManagerProvider(String hostname) {
|
||||
this.hostname = hostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostName() {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509ExtendedTrustManager getTrustManager() {
|
||||
try {
|
||||
logger.trace("Use self-signed certificate downloaded from Vizio TV.");
|
||||
return PEMTrustManager.getInstanceFromServer("https://" + getHostName());
|
||||
} catch (CertificateException | MalformedURLException e) {
|
||||
logger.debug("An unexpected exception occurred - returning a TrustAllTrustManager: {}", e.getMessage(), e);
|
||||
}
|
||||
return TrustAllTrustManager.getInstance();
|
||||
}
|
||||
}
|
@ -107,7 +107,7 @@ public class VizioCommandExtension extends AbstractConsoleCommandExtension {
|
||||
Random rng = new Random();
|
||||
|
||||
int pairingDeviceId = rng.nextInt(100000);
|
||||
int pairingToken = communicator.starPairing(args[2], pairingDeviceId).getItem()
|
||||
int pairingToken = communicator.startPairing(args[2], pairingDeviceId).getItem()
|
||||
.getPairingReqToken();
|
||||
if (pairingToken != -1) {
|
||||
handler.setPairingDeviceId(pairingDeviceId);
|
||||
|
@ -25,11 +25,11 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.openhab.binding.vizio.internal.VizioConfiguration;
|
||||
import org.openhab.binding.vizio.internal.VizioException;
|
||||
import org.openhab.binding.vizio.internal.VizioStateDescriptionOptionProvider;
|
||||
import org.openhab.binding.vizio.internal.communication.VizioCommunicator;
|
||||
import org.openhab.binding.vizio.internal.communication.VizioTlsTrustManagerProvider;
|
||||
import org.openhab.binding.vizio.internal.dto.app.CurrentApp;
|
||||
import org.openhab.binding.vizio.internal.dto.applist.VizioApp;
|
||||
import org.openhab.binding.vizio.internal.dto.applist.VizioApps;
|
||||
@ -40,7 +40,7 @@ import org.openhab.binding.vizio.internal.dto.inputlist.InputList;
|
||||
import org.openhab.binding.vizio.internal.dto.power.PowerMode;
|
||||
import org.openhab.binding.vizio.internal.enums.KeyCommand;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.io.net.http.TlsTrustManagerProvider;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.library.types.NextPreviousType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.PercentType;
|
||||
@ -53,12 +53,11 @@ import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.util.ThingWebClientUtil;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.StateOption;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -74,11 +73,11 @@ import com.google.gson.JsonSyntaxException;
|
||||
@NonNullByDefault
|
||||
public class VizioHandler extends BaseThingHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(VizioHandler.class);
|
||||
private final HttpClient httpClient;
|
||||
private final HttpClientFactory httpClientFactory;
|
||||
private @Nullable HttpClient httpClient;
|
||||
private final VizioStateDescriptionOptionProvider stateDescriptionProvider;
|
||||
private final String dbAppsJson;
|
||||
|
||||
private @Nullable ServiceRegistration<?> serviceRegistration;
|
||||
private @Nullable ScheduledFuture<?> refreshJob;
|
||||
private @Nullable ScheduledFuture<?> metadataRefreshJob;
|
||||
|
||||
@ -97,13 +96,13 @@ public class VizioHandler extends BaseThingHandler {
|
||||
private boolean powerOn = false;
|
||||
private boolean debounce = true;
|
||||
|
||||
public VizioHandler(Thing thing, HttpClient httpClient,
|
||||
public VizioHandler(Thing thing, HttpClientFactory httpClientFactory,
|
||||
VizioStateDescriptionOptionProvider stateDescriptionProvider, String vizioAppsJson) {
|
||||
super(thing);
|
||||
this.httpClient = httpClient;
|
||||
this.httpClientFactory = httpClientFactory;
|
||||
this.stateDescriptionProvider = stateDescriptionProvider;
|
||||
this.dbAppsJson = vizioAppsJson;
|
||||
this.communicator = new VizioCommunicator(httpClient, EMPTY, -1, EMPTY);
|
||||
this.communicator = new VizioCommunicator(httpClientFactory.getCommonHttpClient(), EMPTY, -1, EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -127,13 +126,22 @@ public class VizioHandler extends BaseThingHandler {
|
||||
host = "[" + host + "]";
|
||||
}
|
||||
|
||||
this.communicator = new VizioCommunicator(httpClient, host, config.port, authToken != null ? authToken : EMPTY);
|
||||
|
||||
// register trustmanager service to allow httpClient to accept self signed cert from the Vizio TV
|
||||
VizioTlsTrustManagerProvider tlsTrustManagerProvider = new VizioTlsTrustManagerProvider(
|
||||
host + ":" + config.port);
|
||||
serviceRegistration = FrameworkUtil.getBundle(getClass()).getBundleContext()
|
||||
.registerService(TlsTrustManagerProvider.class.getName(), tlsTrustManagerProvider, null);
|
||||
final String httpClientName = ThingWebClientUtil.buildWebClientConsumerName(thing.getUID(), null);
|
||||
try {
|
||||
httpClient = httpClientFactory.createHttpClient(httpClientName, new SslContextFactory.Client(true));
|
||||
final HttpClient localHttpClient = this.httpClient;
|
||||
if (localHttpClient != null) {
|
||||
localHttpClient.start();
|
||||
this.communicator = new VizioCommunicator(localHttpClient, host, config.port,
|
||||
authToken != null ? authToken : EMPTY);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error(
|
||||
"Long running HttpClient for Vizio handler {} cannot be started. Creating Handler failed. Exception: {}",
|
||||
httpClientName, e.getMessage(), e);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (authToken == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
|
||||
@ -363,11 +371,14 @@ public class VizioHandler extends BaseThingHandler {
|
||||
this.metadataRefreshJob = null;
|
||||
}
|
||||
|
||||
ServiceRegistration<?> localServiceRegistration = serviceRegistration;
|
||||
if (localServiceRegistration != null) {
|
||||
// remove trustmanager service
|
||||
localServiceRegistration.unregister();
|
||||
serviceRegistration = null;
|
||||
try {
|
||||
HttpClient localHttpClient = this.httpClient;
|
||||
if (localHttpClient != null) {
|
||||
localHttpClient.stop();
|
||||
}
|
||||
this.httpClient = null;
|
||||
} catch (Exception e) {
|
||||
logger.debug("Unable to stop Vizio httpClient. Exception: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user