mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 10:14:36 +00:00
Added https to web and api that will use java keytool
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.bwssystems.HABridge</groupId>
|
||||
<artifactId>ha-bridge</artifactId>
|
||||
<version>5.3.0RC9</version>
|
||||
<version>5.3.0RC10</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HA Bridge</name>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -9,7 +9,10 @@ public class BridgeSecurityDescriptor {
|
||||
private String execGarden;
|
||||
private boolean secureHueApi;
|
||||
private Map<String, WhitelistEntry> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,9 @@ public class BridgeSettingsDescriptor {
|
||||
@SerializedName("seedid")
|
||||
@Expose
|
||||
private Integer seedid;
|
||||
@SerializedName("haaddressessecured")
|
||||
@Expose
|
||||
private boolean haaddressessecured;
|
||||
// @SerializedName("activeloggers")
|
||||
// @Expose
|
||||
// private List<NameValue> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,14 +1,34 @@
|
||||
<div class="form-container ngdialog-message" ng-controller="SecurityDialogCtrl">
|
||||
|
||||
<form name="securityForm" role="form">
|
||||
<legend class="form-label">Update Security Settings</legend>
|
||||
<legend class="form-label">Update Security Settings</legend>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Use Link Button</label>
|
||||
<input type="checkbox"
|
||||
<label>Use HTTPS</label>
|
||||
<input type="checkbox"
|
||||
ng-model="useHttps" ng-true-value=true
|
||||
ng-false-value=false /> {{useHttps}}
|
||||
<div>
|
||||
<label>Keyfile Path</label>
|
||||
<input id="keyfilePath" name="keyfilePath" class="form-control"
|
||||
type="text" ng-model="keyfilePath" placeholder="the keyfile path"/>
|
||||
<label>Keyfile Password</label>
|
||||
<input id="keyfilePassword" name="keyfilePassword" class="form-control" type="password" ng-model="keyfilePassword"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Use Link Button</label>
|
||||
<input type="checkbox"
|
||||
ng-model="useLinkButton" ng-true-value=true
|
||||
ng-false-value=false /> {{useLinkButton}}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-group">
|
||||
<label>Exec Garden</label>
|
||||
<input id="execGarden" name="execGarden" class="form-control"
|
||||
type="text" ng-model="execGarden" placeholder="execGarden path"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Use username/password for HUE Api</label>
|
||||
<input type="checkbox"
|
||||
ng-model="secureHueApi" ng-true-value=true
|
||||
|
||||
Reference in New Issue
Block a user