Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ihc] Support for TLSv1.2 #10856

Merged
merged 3 commits into from
Jun 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions bundles/org.openhab.binding.ihc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ This binding supports one ThingType: `controller`.

The `controller` Thing has the following configuration parameters:

| Parameter | Description | Required | Default value |
|-----------------------------|------------------------------------------------------------------------------------------------------------------------------|----------|---------------|
| hostname | Network/IP address of the IHC / ELKO controller without https prefix, but can contain TCP port if default port is not used. | yes | |
| username | User name to login to the IHC / ELKO controller. | yes | |
| password | Password to login to the IHC / ELKO controller. | yes | |
| timeout | Timeout in milliseconds to communicate to IHC / ELKO controller. | no | 5000 |
| loadProjectFile | Load project file from controller. | no | true |
| createChannelsAutomatically | Create channels automatically from project file. Project file loading parameter should be enabled as well. | no | true |
| Parameter | Description | Required | Default value |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|---------------|
| hostname | Network/IP address of the IHC / ELKO controller without https prefix, but can contain TCP port if default port is not used. | yes | |
| username | User name to login to the IHC / ELKO controller. | yes | |
| password | Password to login to the IHC / ELKO controller. | yes | |
| timeout | Timeout in milliseconds to communicate to IHC / ELKO controller. | no | 5000 |
| loadProjectFile | Load project file from controller. | no | true |
| createChannelsAutomatically | Create channels automatically from project file. Project file loading parameter should be enabled as well. | no | true |
| tlsVersion | TLS version used for controller communication. Choose `TLSv1` for older firmware versions and `TLSv1.2` for never versions (since fall 2021). `AUTO` mode try to recognize correct version. | no | TLSv1 |


## Channels
Expand Down Expand Up @@ -148,7 +149,7 @@ Will send TOGGLE (ON/OFF) command to Dimmer test item when short button press is
### example.things

```xtend
ihc:controller:elko [ hostname="192.168.1.2", username="openhab", password="secret", timeout=5000, loadProjectFile=true, createChannelsAutomatically=false ] {
ihc:controller:elko [ hostname="192.168.1.2", username="openhab", password="secret", timeout=5000, loadProjectFile=true, createChannelsAutomatically=false, tlsVersion="TLSv1" ] {
Channels:
Type switch : my_test_switch "My Test Switch" [ resourceId=3988827 ]
Type contact : my_test_contact "My Test Contact" [ resourceId=3988827 ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ public class IhcConfiguration {
public int timeout;
public boolean loadProjectFile;
public boolean createChannelsAutomatically;
public String tlsVersion;

@Override
public String toString() {
return "[" + "hostname=" + hostname + ", username=" + username + ", password=******" + ", timeout=" + timeout
+ ", loadProjectFile=" + loadProjectFile + ", createChannelsAutomatically="
+ createChannelsAutomatically + "]";
+ createChannelsAutomatically + ", tlsVersion=" + tlsVersion + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import org.openhab.binding.ihc.internal.ws.datatypes.WSTimeManagerSettings;
import org.openhab.binding.ihc.internal.ws.exeptions.ConversionException;
import org.openhab.binding.ihc.internal.ws.exeptions.IhcExecption;
import org.openhab.binding.ihc.internal.ws.exeptions.IhcFatalExecption;
import org.openhab.binding.ihc.internal.ws.projectfile.IhcEnumValue;
import org.openhab.binding.ihc.internal.ws.projectfile.ProjectFileUtils;
import org.openhab.binding.ihc.internal.ws.resourcevalues.WSBooleanValue;
Expand Down Expand Up @@ -534,7 +535,7 @@ private void connect() throws IhcExecption {
setConnectingState(true);
logger.debug("Connecting to IHC / ELKO LS controller [hostname='{}', username='{}'].", conf.hostname,
conf.username);
ihc = new IhcClient(conf.hostname, conf.username, conf.password, conf.timeout);
ihc = new IhcClient(conf.hostname, conf.username, conf.password, conf.timeout, conf.tlsVersion);
ihc.openConnection();
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE,
"Initializing communication to the IHC / ELKO controller");
Expand Down Expand Up @@ -883,6 +884,11 @@ private void reconnectCheck() {
}
connect();
setReconnectRequest(false);
} catch (IhcFatalExecption e) {
logger.warn("Can't open connection to controller {}", e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
setReconnectRequest(false);
return;
} catch (IhcExecption e) {
logger.debug("Can't open connection to controller {}", e.getMessage());
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import org.openhab.binding.ihc.internal.ws.datatypes.WSSystemInfo;
import org.openhab.binding.ihc.internal.ws.datatypes.WSTimeManagerSettings;
import org.openhab.binding.ihc.internal.ws.exeptions.IhcExecption;
import org.openhab.binding.ihc.internal.ws.exeptions.IhcFatalExecption;
import org.openhab.binding.ihc.internal.ws.exeptions.IhcTlsExecption;
import org.openhab.binding.ihc.internal.ws.http.IhcConnectionPool;
import org.openhab.binding.ihc.internal.ws.resourcevalues.WSResourceValue;
import org.openhab.binding.ihc.internal.ws.services.IhcAirlinkManagementService;
Expand All @@ -60,6 +62,10 @@ public enum ConnectionState {
CONNECTED
}

public static final String TLS_VER_AUTO = "AUTO";
public static final String TLS_VER_V1 = "TLSv1";
public static final String TLS_VER_V1_2 = "TLSv1.2";

public static final String CONTROLLER_STATE_READY = "text.ctrl.state.ready";
public static final String CONTROLLER_STATE_INITIALIZE = "text.ctrl.state.initialize";

Expand Down Expand Up @@ -88,6 +94,7 @@ public enum ConnectionState {
private String username;
private String password;
private String host;
private String tlsVersion;

/** Timeout in milliseconds */
private int timeout;
Expand All @@ -96,14 +103,15 @@ public enum ConnectionState {
private List<IhcEventListener> eventListeners = new ArrayList<>();

public IhcClient(String host, String username, String password) {
this(host, username, password, 5000);
this(host, username, password, 5000, TLS_VER_V1);
}

public IhcClient(String host, String username, String password, int timeout) {
public IhcClient(String host, String username, String password, int timeout, String tlsVersion) {
this.host = host;
this.username = username;
this.password = password;
this.timeout = timeout;
this.tlsVersion = tlsVersion;
}

public synchronized ConnectionState getConnectionState() {
Expand Down Expand Up @@ -168,10 +176,23 @@ public void closeConnection() throws IhcExecption {
* @throws IhcExecption
*/
public void openConnection() throws IhcExecption {
logger.debug("Opening connection");
if (TLS_VER_AUTO.equalsIgnoreCase(tlsVersion)) {
try {
openConnection(TLS_VER_V1);
} catch (IhcTlsExecption e) {
logger.debug("Connection failed with TLS {}, trying with TLS {}", TLS_VER_V1, TLS_VER_V1_2);
openConnection(TLS_VER_V1_2);
}
} else {
openConnection(tlsVersion);
}
}

private void openConnection(String tlsVersion) throws IhcExecption {
logger.debug("Opening connection with TLS version {}", tlsVersion);

setConnectionState(ConnectionState.CONNECTING);
ihcConnectionPool = new IhcConnectionPool();
ihcConnectionPool = new IhcConnectionPool(tlsVersion);
authenticationService = new IhcAuthenticationService(host, timeout, ihcConnectionPool);
WSLoginResult loginResult = authenticationService.authenticate(username, password, "treeview");

Expand All @@ -181,18 +202,18 @@ public void openConnection() throws IhcExecption {
setConnectionState(ConnectionState.DISCONNECTED);

if (loginResult.isLoginFailedDueToAccountInvalid()) {
throw new IhcExecption("login failed because of invalid account");
throw new IhcFatalExecption("login failed because of invalid account");
}

if (loginResult.isLoginFailedDueToConnectionRestrictions()) {
throw new IhcExecption("login failed because of connection restrictions");
throw new IhcFatalExecption("login failed because of connection restrictions");
}

if (loginResult.isLoginFailedDueToInsufficientUserRights()) {
throw new IhcExecption("login failed because of insufficient user rights");
throw new IhcFatalExecption("login failed because of insufficient user rights");
}

throw new IhcExecption("login failed because of unknown reason");
throw new IhcFatalExecption("login failed because of unknown reason");
}

logger.debug("Connection successfully opened");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2010-2021 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.ihc.internal.ws.exeptions;

/**
* Exception for handling fatal communication errors to controller.
*
* @author Pauli Anttila - Initial contribution
*/
public class IhcFatalExecption extends IhcExecption {

private static final long serialVersionUID = -8107948791816894352L;

public IhcFatalExecption() {
}

public IhcFatalExecption(String message) {
super(message);
}

public IhcFatalExecption(String message, Throwable cause) {
super(message, cause);
}

public IhcFatalExecption(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2010-2021 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.ihc.internal.ws.exeptions;

/**
* Exception for handling TLS communication errors to controller.
*
* @author Pauli Anttila - Initial contribution
*/
public class IhcTlsExecption extends IhcFatalExecption {

private static final long serialVersionUID = -1366186910684967044L;

public IhcTlsExecption() {
}

public IhcTlsExecption(String message) {
super(message);
}

public IhcTlsExecption(String message, Throwable cause) {
super(message, cause);
}

public IhcTlsExecption(Throwable cause) {
super(cause);
}
}
Loading