Added https to web and api that will use java keytool

This commit is contained in:
BWS Systems
2019-07-10 16:07:22 -05:00
parent a5ee0aafc8
commit 53be3ba213
9 changed files with 194 additions and 19 deletions

View File

@@ -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>

View File

@@ -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");

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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");

View File

@@ -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) {

View File

@@ -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