diff --git a/pom.xml b/pom.xml index cce4885..758d4ee 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.bwssystems.HABridge ha-bridge - 5.3.0RC9 + 5.3.0RC10 jar HA Bridge diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java b/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java index 4d0d623..03a6392 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSecurity.java @@ -38,7 +38,7 @@ public class BridgeSecurity { (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, }; - private char[] habridgeKey; + private static char[] habridgeKey; private String execGarden; private BridgeSecurityDescriptor securityDescriptor; private boolean settingsChanged; @@ -146,7 +146,16 @@ public class BridgeSecurity { public String getExecGarden() { return execGarden; } - public void setUseLinkButton(boolean useThis) { + + String getKeyfilePath() { + return securityDescriptor.getKeyfilePath(); + } + + String getKeyfilePassword() { + return securityDescriptor.getKeyfilePassword(); + } + + private void setUseLinkButton(boolean useThis) { securityDescriptor.setUseLinkButton(useThis); settingsChanged = true; } @@ -155,16 +164,77 @@ public class BridgeSecurity { return securityDescriptor.isSecureHueApi(); } - public void setSecureHueApi(boolean theState) { - securityDescriptor.setSecureHueApi(theState); + public boolean isUseHttps() { + return securityDescriptor.isUseHttps(); } + + public boolean isKeyfilePW() { + if(securityDescriptor.getKeyfilePassword() != null && !securityDescriptor.getKeyfilePassword().trim().isEmpty()) { + return true; + } + + return false; + } + + private void setSecureHueApi(boolean theState) { + securityDescriptor.setSecureHueApi(theState); + settingsChanged = true; + } + + private void setUseHttps(boolean usehttps, String keyfilepath, String keyfilepassword) { + if(usehttps) { + if(!isUseHttps()) { + securityDescriptor.setKeyfilePath(keyfilepath); + securityDescriptor.setKeyfilePassword(keyfilepassword); + securityDescriptor.setUseHttps(usehttps); + settingsChanged = true; + } else { + if(!keyfilepassword.equals("########")) { + securityDescriptor.setKeyfilePassword(keyfilepassword); + settingsChanged = true; + } + + if(!securityDescriptor.getKeyfilePath().equals(keyfilepath)) { + securityDescriptor.setKeyfilePath(keyfilepath); + settingsChanged = true; + } + } + } else { + if(isUseHttps()) { + securityDescriptor.setKeyfilePassword(""); + securityDescriptor.setKeyfilePath(""); + securityDescriptor.setUseHttps(usehttps); + settingsChanged = true; + } + } + } + public SecurityInfo getSecurityInfo() { SecurityInfo theInfo = new SecurityInfo(); theInfo.setUseLinkButton(isUseLinkButton()); theInfo.setSecureHueApi(isSecureHueApi()); theInfo.setSecure(isSecure()); + theInfo.setUseHttps(isUseHttps()); + theInfo.setKeyfilePath(securityDescriptor.getKeyfilePath()); + + if(isKeyfilePW()) { + theInfo.setKeyfilePassword("########"); + } + else { + theInfo.setKeyfilePassword(""); + } + if(isSecure()) { + theInfo.setExecGarden(execGarden); + } return theInfo; } + + public void setSecurityDataByInfo(SecurityInfo theInfo) { + setUseLinkButton(theInfo.isUseLinkButton()); + setSecureHueApi(theInfo.isSecureHueApi()); + setUseHttps(theInfo.isUseHttps(), theInfo.getKeyfilePath(), theInfo.getKeyfilePassword()); + } + public LoginResult validatePassword(User targetUser) throws IOException { LoginResult result = new LoginResult(); if(targetUser != null && targetUser.getUsername() != null) { @@ -324,7 +394,7 @@ public class BridgeSecurity { } } - private String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException { + static String encrypt(String property) throws GeneralSecurityException, UnsupportedEncodingException { SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey key = keyFactory.generateSecret(new PBEKeySpec(habridgeKey)); Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); @@ -336,7 +406,7 @@ public class BridgeSecurity { return Base64.getEncoder().encodeToString(bytes); } - private String decrypt(String property) throws GeneralSecurityException, IOException { + static String decrypt(String property) throws GeneralSecurityException, IOException { SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey key = keyFactory.generateSecret(new PBEKeySpec(habridgeKey)); Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSecurityDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSecurityDescriptor.java index 19bf17b..07ec177 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSecurityDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSecurityDescriptor.java @@ -9,7 +9,10 @@ public class BridgeSecurityDescriptor { private String execGarden; private boolean secureHueApi; private Map whitelist; - + private boolean useHttps; + private String keyfilePassword; + private String keyfilePath; + public BridgeSecurityDescriptor() { super(); this.setUseLinkButton(false); @@ -67,4 +70,28 @@ public class BridgeSecurityDescriptor { return secureFlag; } + + public boolean isUseHttps() { + return useHttps; + } + + public void setUseHttps(boolean useHttps) { + this.useHttps = useHttps; + } + + public String getKeyfilePassword() { + return keyfilePassword; + } + + public void setKeyfilePassword(String keyfilePassword) { + this.keyfilePassword = keyfilePassword; + } + + public String getKeyfilePath() { + return keyfilePath; + } + + public void setKeyfilePath(String keyfilePath) { + this.keyfilePath = keyfilePath; + } } diff --git a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java index c43f5cb..31f4623 100644 --- a/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java +++ b/src/main/java/com/bwssystems/HABridge/BridgeSettingsDescriptor.java @@ -129,6 +129,9 @@ public class BridgeSettingsDescriptor { @SerializedName("seedid") @Expose private Integer seedid; + @SerializedName("haaddressessecured") + @Expose + private boolean haaddressessecured; // @SerializedName("activeloggers") // @Expose // private List activeloggers; @@ -188,6 +191,7 @@ public class BridgeSettingsDescriptor { this.tracestate = false; this.upnporiginal = false; this.seedid = 100; + this.haaddressessecured = false; } public String getUpnpConfigAddress() { @@ -255,6 +259,7 @@ public class BridgeSettingsDescriptor { } public IpList getVeraAddress() { + return veraaddress; } @@ -835,4 +840,11 @@ public class BridgeSettingsDescriptor { return true; } + public boolean isHaaddressessecured() { + return haaddressessecured; + } + + public void setHaaddressessecured(boolean haaddressessecured) { + this.haaddressessecured = haaddressessecured; + } } diff --git a/src/main/java/com/bwssystems/HABridge/HABridge.java b/src/main/java/com/bwssystems/HABridge/HABridge.java index 5a937fb..fa5c66e 100644 --- a/src/main/java/com/bwssystems/HABridge/HABridge.java +++ b/src/main/java/com/bwssystems/HABridge/HABridge.java @@ -54,9 +54,13 @@ public class HABridge { bridgeSettings = new BridgeSettings(); // sparkjava config directive to set html static file location for Jetty while(!bridgeSettings.getBridgeControl().isStop()) { - bridgeSettings.buildSettings(); - bridgeSettings.getBridgeSecurity().removeTestUsers(); log.info("HA Bridge (v{}) initializing....", theVersion.getVersion() ); + bridgeSettings.buildSettings(); + if(bridgeSettings.getBridgeSecurity().isUseHttps()) { + secure(bridgeSettings.getBridgeSecurity().getKeyfilePath(), bridgeSettings.getBridgeSecurity().getKeyfilePassword(), null, null); + log.info("Using https for web and api calls"); + } + bridgeSettings.getBridgeSecurity().removeTestUsers(); // sparkjava config directive to set ip address for the web server to listen on ipAddress(bridgeSettings.getBridgeSettingsDescriptor().getWebaddress()); // sparkjava config directive to set port for the web server to listen on diff --git a/src/main/java/com/bwssystems/HABridge/SecurityInfo.java b/src/main/java/com/bwssystems/HABridge/SecurityInfo.java index 11ed72c..d2fd985 100644 --- a/src/main/java/com/bwssystems/HABridge/SecurityInfo.java +++ b/src/main/java/com/bwssystems/HABridge/SecurityInfo.java @@ -4,6 +4,10 @@ public class SecurityInfo { private boolean useLinkButton; private boolean secureHueApi; private boolean isSecure; + private String execGarden; + private boolean useHttps; + private String keyfilePath; + private String keyfilePassword; public boolean isUseLinkButton() { return useLinkButton; @@ -23,4 +27,36 @@ public class SecurityInfo { public void setSecure(boolean isSecure) { this.isSecure = isSecure; } + + public boolean isUseHttps() { + return useHttps; + } + + public void setUseHttps(boolean useHttps) { + this.useHttps = useHttps; + } + + public String getKeyfilePath() { + return keyfilePath; + } + + public void setKeyfilePath(String keyfilePath) { + this.keyfilePath = keyfilePath; + } + + public String getExecGarden() { + return execGarden; + } + + public void setExecGarden(String execGarden) { + this.execGarden = execGarden; + } + + public String getKeyfilePassword() { + return keyfilePassword; + } + + public void setKeyfilePassword(String keyfilePassword) { + this.keyfilePassword = keyfilePassword; + } } diff --git a/src/main/java/com/bwssystems/HABridge/SystemControl.java b/src/main/java/com/bwssystems/HABridge/SystemControl.java index e83d770..bbb97c0 100644 --- a/src/main/java/com/bwssystems/HABridge/SystemControl.java +++ b/src/main/java/com/bwssystems/HABridge/SystemControl.java @@ -314,8 +314,7 @@ public class SystemControl { post(SYSTEM_CONTEXT + "/changesecurityinfo", (request, response) -> { log.debug("changesecurityinfo...."); SecurityInfo theInfo = new Gson().fromJson(request.body(), SecurityInfo.class); - bridgeSettings.getBridgeSecurity().setUseLinkButton(theInfo.isUseLinkButton()); - bridgeSettings.getBridgeSecurity().setSecureHueApi(theInfo.isSecureHueApi()); + bridgeSettings.getBridgeSecurity().setSecurityDataByInfo(theInfo); bridgeSettings.save(bridgeSettings.getBridgeSettingsDescriptor()); response.status(HttpStatus.SC_OK); response.type("application/json"); diff --git a/src/main/resources/public/scripts/app.js b/src/main/resources/public/scripts/app.js index 23cc8b2..0afe010 100644 --- a/src/main/resources/public/scripts/app.js +++ b/src/main/resources/public/scripts/app.js @@ -366,12 +366,15 @@ app.service('bridgeService', function ($rootScope, $http, $base64, $location, ng ); }; - this.changeSecuritySettings = function (useLinkButton, secureHueApi, execGarden) { + this.changeSecuritySettings = function (useLinkButton, secureHueApi, execGarden, useHttps, keyfilePath, keyfilePassword) { var newSecurityInfo = {}; newSecurityInfo = { useLinkButton: useLinkButton, secureHueApi: secureHueApi, - execGarden: execGarden + execGarden: execGarden, + useHttps: useHttps, + keyfilePath: keyfilePath, + keyfilePassword: keyfilePassword }; return $http.post(this.state.systemsbase + "/changesecurityinfo", newSecurityInfo).then( function (response) { @@ -2287,13 +2290,17 @@ app.controller('SecurityDialogCtrl', function ($scope, bridgeService, ngDialog) $scope.useLinkButton = bridgeService.state.securityInfo.useLinkButton; $scope.execGarden = bridgeService.state.securityInfo.execGarden; $scope.isSecure = bridgeService.state.securityInfo.isSecure; + $scope.useHttps = bridgeService.state.securityInfo.useHttps; + $scope.keyfilePath = bridgeService.state.securityInfo.keyfilePath; + $scope.keyfilePassword = bridgeService.state.securityInfo.keyfilePassword; + $scope.matched = false; $scope.addingUser = false; $scope.showPassword = $scope.isSecure; $scope.firstTime = true; $scope.setSecurityInfo = function () { - bridgeService.changeSecuritySettings($scope.useLinkButton, $scope.secureHueApi, $scope.execGarden); + bridgeService.changeSecuritySettings($scope.useLinkButton, $scope.secureHueApi, $scope.execGarden, $scope.useHttps, $scope.keyfilePath, $scope.keyfilePassword); }; $scope.changePassword = function (password, password2) { diff --git a/src/main/resources/public/views/securitydialog.html b/src/main/resources/public/views/securitydialog.html index 841612f..671f89d 100644 --- a/src/main/resources/public/views/securitydialog.html +++ b/src/main/resources/public/views/securitydialog.html @@ -1,14 +1,34 @@ - Update Security Settings + Update Security Settings + - Use Link Button - Use HTTPS + {{useHttps}} + + Keyfile Path + + Keyfile Password + + + + + + Use Link Button + {{useLinkButton}} - + + Exec Garden + + + Use username/password for HUE Api