From 70d807e2bff920e795cff40d2470f534bdca601a Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Sat, 3 Dec 2016 14:01:06 +0300 Subject: [PATCH] Datasources serialization fix. Secure model refactoring --- .../core/application/DBeaverApplication.java | 8 +- .../org/jkiss/dbeaver/core/DBeaverCore.java | 11 ++- .../dbeaver/core/EclipseApplication.java | 8 +- .../dbeaver/registry/DataSourceRegistry.java | 97 +++++++++---------- ...entSecurity.java => DBASecureStorage.java} | 2 +- .../dbeaver/model/app/DBPApplication.java | 2 +- .../jkiss/dbeaver/model/app/DBPPlatform.java | 3 + .../connection/DBPConnectionBootstrap.java | 10 ++ ...ecurity.java => DefaultSecureStorage.java} | 16 +-- 9 files changed, 82 insertions(+), 75 deletions(-) rename plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/{DBAClientSecurity.java => DBASecureStorage.java} (96%) rename plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/{DefaultClientSecurity.java => DefaultSecureStorage.java} (70%) diff --git a/plugins/org.jkiss.dbeaver.core.application/src/org/jkiss/dbeaver/core/application/DBeaverApplication.java b/plugins/org.jkiss.dbeaver.core.application/src/org/jkiss/dbeaver/core/application/DBeaverApplication.java index 0d7559f557..990238a1f2 100644 --- a/plugins/org.jkiss.dbeaver.core.application/src/org/jkiss/dbeaver/core/application/DBeaverApplication.java +++ b/plugins/org.jkiss.dbeaver.core.application/src/org/jkiss/dbeaver/core/application/DBeaverApplication.java @@ -41,9 +41,9 @@ import org.jkiss.dbeaver.core.DBeaverUI; import org.jkiss.dbeaver.core.application.rpc.DBeaverInstanceServer; import org.jkiss.dbeaver.core.application.rpc.IInstanceController; import org.jkiss.dbeaver.core.application.rpc.InstanceClient; -import org.jkiss.dbeaver.model.app.DBAClientSecurity; +import org.jkiss.dbeaver.model.app.DBASecureStorage; import org.jkiss.dbeaver.model.app.DBPApplication; -import org.jkiss.dbeaver.model.impl.app.DefaultClientSecurity; +import org.jkiss.dbeaver.model.impl.app.DefaultSecureStorage; import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.dbeaver.utils.SystemVariablesResolver; import org.jkiss.utils.ArrayUtils; @@ -378,8 +378,8 @@ public class DBeaverApplication implements IApplication, DBPApplication { @NotNull @Override - public DBAClientSecurity getClientSecurity() { - return DefaultClientSecurity.INSTANCE; + public DBASecureStorage getSecureStorage() { + return DefaultSecureStorage.INSTANCE; } private class ProxyPrintStream extends OutputStream { diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/DBeaverCore.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/DBeaverCore.java index c000227ec2..948151f8cb 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/DBeaverCore.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/DBeaverCore.java @@ -29,10 +29,7 @@ import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.*; -import org.jkiss.dbeaver.model.app.DBACertificateStorage; -import org.jkiss.dbeaver.model.app.DBPApplication; -import org.jkiss.dbeaver.model.app.DBPPlatform; -import org.jkiss.dbeaver.model.app.DBPProjectManager; +import org.jkiss.dbeaver.model.app.*; import org.jkiss.dbeaver.model.data.DBDRegistry; import org.jkiss.dbeaver.model.edit.DBERegistry; import org.jkiss.dbeaver.model.impl.app.DefaultCertificateStorage; @@ -368,6 +365,12 @@ public class DBeaverCore implements DBPPlatform { return certificateStorage; } + @NotNull + @Override + public DBASecureStorage getSecureStorage() { + return application.getSecureStorage(); + } + public ProjectRegistry getProjectRegistry() { return projectRegistry; diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/EclipseApplication.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/EclipseApplication.java index 8c7ca7b404..ccf96f15b7 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/EclipseApplication.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/core/EclipseApplication.java @@ -18,9 +18,9 @@ package org.jkiss.dbeaver.core; import org.jkiss.code.NotNull; -import org.jkiss.dbeaver.model.app.DBAClientSecurity; +import org.jkiss.dbeaver.model.app.DBASecureStorage; import org.jkiss.dbeaver.model.app.DBPApplication; -import org.jkiss.dbeaver.model.impl.app.DefaultClientSecurity; +import org.jkiss.dbeaver.model.impl.app.DefaultSecureStorage; /** * EclipseApplication @@ -34,7 +34,7 @@ class EclipseApplication implements DBPApplication { @NotNull @Override - public DBAClientSecurity getClientSecurity() { - return DefaultClientSecurity.INSTANCE; + public DBASecureStorage getSecureStorage() { + return DefaultSecureStorage.INSTANCE; } } diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/registry/DataSourceRegistry.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/registry/DataSourceRegistry.java index 043fc2a7d3..12b830ce2c 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/registry/DataSourceRegistry.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/registry/DataSourceRegistry.java @@ -31,6 +31,7 @@ import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.core.DBeaverCore; import org.jkiss.dbeaver.core.DBeaverNature; import org.jkiss.dbeaver.model.*; +import org.jkiss.dbeaver.model.app.DBASecureStorage; import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry; import org.jkiss.dbeaver.model.app.DBPPlatform; import org.jkiss.dbeaver.model.connection.DBPConnectionBootstrap; @@ -542,13 +543,7 @@ public class DataSourceRegistry implements DBPDataSourceRegistry clearSecuredPassword(dataSource, null); if (dataSource.isSavePassword() && !CommonUtils.isEmpty(connectionInfo.getUserPassword())) { - if (!saveSecuredPassword(dataSource, null, connectionInfo.getUserPassword())) { - try { - xml.addAttribute(RegistryConstants.ATTR_PASSWORD, ENCRYPTOR.encrypt(connectionInfo.getUserPassword())); - } catch (EncryptionException e) { - log.error("Error encrypting password", e); - } - } + saveSecuredPassword(xml, dataSource, null, connectionInfo.getUserPassword()); } if (!CommonUtils.isEmpty(connectionInfo.getClientHomeId())) { xml.addAttribute(RegistryConstants.ATTR_HOME, connectionInfo.getClientHomeId()); @@ -591,17 +586,8 @@ public class DataSourceRegistry implements DBPDataSourceRegistry xml.addAttribute(RegistryConstants.ATTR_ENABLED, configuration.isEnabled()); xml.addAttribute(RegistryConstants.ATTR_USER, CommonUtils.notEmpty(configuration.getUserName())); xml.addAttribute(RegistryConstants.ATTR_SAVE_PASSWORD, configuration.isSavePassword()); - if (configuration.isSavePassword() && !CommonUtils.isEmpty(configuration.getPassword())) { - String encPassword = configuration.getPassword(); - if (!CommonUtils.isEmpty(encPassword)) { - try { - encPassword = ENCRYPTOR.encrypt(encPassword); - } - catch (EncryptionException e) { - log.error("Can't encrypt password. Save it as is", e); - } - } - xml.addAttribute(RegistryConstants.ATTR_PASSWORD, encPassword); + if (configuration.isSavePassword()) { + saveSecuredPassword(xml, dataSource, "network/" + configuration.getId(), configuration.getPassword()); } for (Map.Entry entry : configuration.getProperties().entrySet()) { xml.startElement(RegistryConstants.TAG_PROPERTY); @@ -615,28 +601,29 @@ public class DataSourceRegistry implements DBPDataSourceRegistry // Save bootstrap info { DBPConnectionBootstrap bootstrap = connectionInfo.getBootstrap(); - xml.startElement(RegistryConstants.TAG_BOOTSTRAP); - if (bootstrap.getDefaultAutoCommit() != null) { - xml.addAttribute(RegistryConstants.ATTR_AUTOCOMMIT, bootstrap.getDefaultAutoCommit()); - } - if (bootstrap.getDefaultTransactionIsolation() != null) { - xml.addAttribute(RegistryConstants.ATTR_TXN_ISOLATION, bootstrap.getDefaultTransactionIsolation()); - } - if (!CommonUtils.isEmpty(bootstrap.getDefaultObjectName())) { - xml.addAttribute(RegistryConstants.ATTR_DEFAULT_OBJECT, bootstrap.getDefaultObjectName()); - } - if (bootstrap.isIgnoreErrors()) { - xml.addAttribute(RegistryConstants.ATTR_IGNORE_ERRORS, true); - } - for (String query : bootstrap.getInitQueries()) { - xml.startElement(RegistryConstants.TAG_QUERY); - xml.addText(query); + if (bootstrap.hasData()) { + xml.startElement(RegistryConstants.TAG_BOOTSTRAP); + if (bootstrap.getDefaultAutoCommit() != null) { + xml.addAttribute(RegistryConstants.ATTR_AUTOCOMMIT, bootstrap.getDefaultAutoCommit()); + } + if (bootstrap.getDefaultTransactionIsolation() != null) { + xml.addAttribute(RegistryConstants.ATTR_TXN_ISOLATION, bootstrap.getDefaultTransactionIsolation()); + } + if (!CommonUtils.isEmpty(bootstrap.getDefaultObjectName())) { + xml.addAttribute(RegistryConstants.ATTR_DEFAULT_OBJECT, bootstrap.getDefaultObjectName()); + } + if (bootstrap.isIgnoreErrors()) { + xml.addAttribute(RegistryConstants.ATTR_IGNORE_ERRORS, true); + } + for (String query : bootstrap.getInitQueries()) { + xml.startElement(RegistryConstants.TAG_QUERY); + xml.addText(query); + xml.endElement(); + } xml.endElement(); } - xml.endElement(); } - xml.endElement(); } @@ -687,22 +674,34 @@ public class DataSourceRegistry implements DBPDataSourceRegistry xml.endElement(); } - private boolean saveSecuredPassword(DataSourceDescriptor dataSource, String subNode, String password) { - try { - ISecurePreferences prefNode = dataSource.getSecurePreferences(); - if (subNode != null) { - prefNode = prefNode.node(subNode); + private void saveSecuredPassword(XMLBuilder xml, DataSourceDescriptor dataSource, String subNode, String password) throws IOException { + boolean saved = false; + final DBASecureStorage secureStorage = getPlatform().getSecureStorage(); + if (secureStorage.useSecurePreferences()) { + try { + ISecurePreferences prefNode = dataSource.getSecurePreferences(); + if (subNode != null) { + for (String nodeName : subNode.split("/")) { + prefNode = prefNode.node(nodeName); + } + } + if (!CommonUtils.isEmpty(password)) { + prefNode.put(RegistryConstants.ATTR_PASSWORD, password, true); + } else { + prefNode.remove(RegistryConstants.ATTR_PASSWORD); + } + saved = true; + } catch (StorageException e) { + log.error("Can't save password in secure storage", e); } - if (!CommonUtils.isEmpty(password)) { - prefNode.put(RegistryConstants.ATTR_PASSWORD, password, true); - } else { - prefNode.remove(RegistryConstants.ATTR_PASSWORD); + } + if (!saved && !CommonUtils.isEmpty(password)) { + try { + xml.addAttribute(RegistryConstants.ATTR_PASSWORD, ENCRYPTOR.encrypt(password)); + } catch (EncryptionException e) { + log.error("Error encrypting password", e); } - } catch (StorageException e) { - log.error("Can't save password in secure storage", e); } - - return false; } private void clearSecuredPassword(DataSourceDescriptor dataSource, String subNode) { diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBAClientSecurity.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBASecureStorage.java similarity index 96% rename from plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBAClientSecurity.java rename to plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBASecureStorage.java index 71133a24bf..321e72c63e 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBAClientSecurity.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBASecureStorage.java @@ -23,7 +23,7 @@ import org.eclipse.equinox.security.storage.ISecurePreferences; /** * Client security manager */ -public interface DBAClientSecurity +public interface DBASecureStorage { boolean useSecurePreferences(); diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPApplication.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPApplication.java index 6a92def858..3f785e20b3 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPApplication.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPApplication.java @@ -28,6 +28,6 @@ public interface DBPApplication boolean isStandalone(); @NotNull - DBAClientSecurity getClientSecurity(); + DBASecureStorage getSecureStorage(); } diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPPlatform.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPPlatform.java index e985508d88..b1759502df 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPPlatform.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/app/DBPPlatform.java @@ -67,6 +67,9 @@ public interface DBPPlatform @NotNull DBACertificateStorage getCertificateStorage(); + @NotNull + DBASecureStorage getSecureStorage(); + @NotNull File getTempFolder(DBRProgressMonitor monitor, String name) throws IOException; diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/connection/DBPConnectionBootstrap.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/connection/DBPConnectionBootstrap.java index dcf781e8e9..d7f0864ad4 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/connection/DBPConnectionBootstrap.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/connection/DBPConnectionBootstrap.java @@ -17,6 +17,8 @@ */ package org.jkiss.dbeaver.model.connection; +import org.jkiss.utils.CommonUtils; + import java.util.*; /** @@ -87,4 +89,12 @@ public class DBPConnectionBootstrap this.ignoreErrors = ignoreErrors; } + public boolean hasData() { + return + defaultAutoCommit != null || + defaultTransactionIsolation != null || + !CommonUtils.isEmpty(defaultObjectName) || + ignoreErrors || + !CommonUtils.isEmpty(initQueries); + } } diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultClientSecurity.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultSecureStorage.java similarity index 70% rename from plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultClientSecurity.java rename to plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultSecureStorage.java index bf600e0576..f5dd57cf44 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultClientSecurity.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/app/DefaultSecureStorage.java @@ -19,22 +19,14 @@ package org.jkiss.dbeaver.model.impl.app; import org.eclipse.equinox.security.storage.ISecurePreferences; import org.eclipse.equinox.security.storage.SecurePreferencesFactory; -import org.jkiss.dbeaver.DBException; -import org.jkiss.dbeaver.Log; -import org.jkiss.dbeaver.model.app.DBACertificateStorage; -import org.jkiss.dbeaver.model.app.DBAClientSecurity; - -import java.io.*; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.security.cert.CertificateFactory; +import org.jkiss.dbeaver.model.app.DBASecureStorage; /** - * DefaultClientSecurity + * DefaultSecureStorage */ -public class DefaultClientSecurity implements DBAClientSecurity { +public class DefaultSecureStorage implements DBASecureStorage { - public static DefaultClientSecurity INSTANCE = new DefaultClientSecurity(); + public static DefaultSecureStorage INSTANCE = new DefaultSecureStorage(); @Override public boolean useSecurePreferences() { -- GitLab