提交 679cf555 编写于 作者: S Serge Rider

#2 MySQL SSL support

上级 2f11ddad
......@@ -269,7 +269,7 @@ public class DB2DataSource extends JDBCDataSource implements DBSObjectSelector,
}
@Override
protected Map<String, String> getInternalConnectionProperties()
protected Map<String, String> getInternalConnectionProperties() throws DBCException
{
Map<String, String> props = new HashMap<>();
props.putAll(DB2DataSourceProvider.getConnectionsProps());
......
......@@ -31,6 +31,7 @@ import org.jkiss.dbeaver.ext.mysql.model.plan.MySQLPlanAnalyser;
import org.jkiss.dbeaver.ext.mysql.model.session.MySQLSessionManager;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPErrorAssistant;
import org.jkiss.dbeaver.model.DBPSecurityManager;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSessionManager;
import org.jkiss.dbeaver.model.exec.*;
......@@ -49,6 +50,9 @@ import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.utils.CommonUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
......@@ -80,13 +84,16 @@ public class MySQLDataSource extends JDBCDataSource implements DBSObjectSelector
@Override
protected Map<String, String> getInternalConnectionProperties()
throws DBCException
{
Map<String, String> props = new HashMap<>(MySQLDataSourceProvider.getConnectionsProps());
Map<String, String> props = new LinkedHashMap<>(MySQLDataSourceProvider.getConnectionsProps());
final DBWHandlerConfiguration sslConfig = getContainer().getActualConnectionConfiguration().getDeclaredHandler(MySQLConstants.HANDLER_SSL);
if (sslConfig != null && sslConfig.isEnabled()) {
props.put("useSSL", "true");
props.put("verifyServerCertificate", String.valueOf(CommonUtils.toBoolean(sslConfig.getProperties().get(MySQLConstants.PROP_VERIFY_SERVER_SERT))));
props.put("requireSSL", String.valueOf(CommonUtils.toBoolean(sslConfig.getProperties().get(MySQLConstants.PROP_REQUIRE_SSL))));
try {
initSSL(props, sslConfig);
} catch (Exception e) {
throw new DBCException("Error configuring SSL certificates", e);
}
}
/*
if (CommonUtils.toBoolean(connectionInfo.getProperty(MySQLConstants.PROP_USE_SSL))) {
......@@ -97,6 +104,41 @@ public class MySQLDataSource extends JDBCDataSource implements DBSObjectSelector
return props;
}
private void initSSL(Map<String, String> props, DBWHandlerConfiguration sslConfig) throws Exception {
props.put("useSSL", "true");
props.put("verifyServerCertificate", String.valueOf(CommonUtils.toBoolean(sslConfig.getProperties().get(MySQLConstants.PROP_VERIFY_SERVER_SERT))));
props.put("requireSSL", String.valueOf(CommonUtils.toBoolean(sslConfig.getProperties().get(MySQLConstants.PROP_REQUIRE_SSL))));
final String caCertProp = sslConfig.getProperties().get(MySQLConstants.PROP_SSL_CA_CERT);
final String clientCertProp = sslConfig.getProperties().get(MySQLConstants.PROP_SSL_CLIENT_CERT);
final String cipherSuites = sslConfig.getProperties().get(MySQLConstants.PROP_SSL_CIPHER_SUITES);
// Trust keystore
if (!CommonUtils.isEmpty(caCertProp)) {
File caCertFile = new File(caCertProp);
String ksId = "ssl-truststore";
final DBPSecurityManager securityManager = getContainer().getApplication().getSecurityManager();
try (InputStream is = new FileInputStream(caCertFile)) {
securityManager.addCertificate(ksId, getContainer().getId(), is);
}
props.put("trustCertificateKeyStoreUrl", securityManager.getKeyStorePath(ksId).toURI().toURL().toString());
}
// Client certificate
if (!CommonUtils.isEmpty(clientCertProp)) {
File clientCertFile = new File(clientCertProp);
String ksId = "ssl-clientstore";
final DBPSecurityManager securityManager = getContainer().getApplication().getSecurityManager();
try (InputStream is = new FileInputStream(clientCertFile)) {
securityManager.addCertificate(ksId, getContainer().getId(), is);
}
props.put("clientCertificateKeyStoreUrl", securityManager.getKeyStorePath(ksId).toURI().toURL().toString());
}
if (!CommonUtils.isEmpty(cipherSuites)) {
props.put("enabledSSLCipherSuites", cipherSuites);
}
}
protected void initializeContextState(@NotNull DBRProgressMonitor monitor, @NotNull JDBCExecutionContext context, boolean setActiveObject) throws DBCException {
if (setActiveObject) {
MySQLCatalog object = getSelectedObject();
......
......@@ -58,6 +58,12 @@ public class MySQLSSLConfigurator extends SSLConfiguratorAbstractUI
requireSSQL = UIUtils.createLabelCheckbox(composite, "Require SSL", false);
veryServerCert = UIUtils.createLabelCheckbox(composite, "Verify server certificate", true);
UIUtils.createControlLabel(composite, "CA certificate");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.minimumWidth = 130;
clientCAText = new TextWithOpenFile(composite, "CA Certificate", new String[] {"*.*", "*.cert", "*.pem", "*"} );
clientCAText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
UIUtils.createControlLabel(composite, "SSL certificate");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.minimumWidth = 130;
......@@ -70,12 +76,6 @@ public class MySQLSSLConfigurator extends SSLConfiguratorAbstractUI
clientKeyText = new TextWithOpenFile(composite, "SSL Certificate", new String[] {"*.*", "*.cert", "*.pem", "*"} );
clientKeyText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
UIUtils.createControlLabel(composite, "CA certificate (optional)");
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.minimumWidth = 130;
clientCAText = new TextWithOpenFile(composite, "CA Certificate", new String[] {"*.*", "*.cert", "*.pem", "*"} );
clientCAText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
cipherSuitesText = UIUtils.createLabelText(composite, "Cipher suites (optional)", "");
}
......
......@@ -159,7 +159,7 @@ public class OracleDataSource extends JDBCDataSource
}
@Override
protected Map<String, String> getInternalConnectionProperties()
protected Map<String, String> getInternalConnectionProperties() throws DBCException
{
return OracleDataSourceProvider.getConnectionsProps();
}
......
......@@ -73,7 +73,7 @@ public class PostgreDataSource extends JDBCDataSource implements DBSObjectSelect
}
@Override
protected Map<String, String> getInternalConnectionProperties()
protected Map<String, String> getInternalConnectionProperties() throws DBCException
{
return PostgreDataSourceProvider.getConnectionsProps();
}
......
......@@ -18,7 +18,10 @@
package org.jkiss.dbeaver.model;
import org.jkiss.dbeaver.DBException;
import java.io.File;
import java.io.InputStream;
import java.security.KeyStore;
/**
......@@ -26,7 +29,9 @@ import java.security.KeyStore;
*/
public interface DBPSecurityManager
{
KeyStore getKeyStore(String ksId);
KeyStore getKeyStore(String ksId) throws DBException;
void addCertificate(String ksId, String certId, InputStream certStream) throws DBException;
File getKeyStorePath(String ksId);
}
......@@ -514,6 +514,7 @@ public abstract class JDBCDataSource
*/
@Nullable
protected Map<String, String> getInternalConnectionProperties()
throws DBCException
{
return null;
}
......
......@@ -17,11 +17,14 @@
*/
package org.jkiss.dbeaver.model.impl.security;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPSecurityManager;
import java.io.File;
import java.io.*;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
/**
* DefaultSecurityManager
......@@ -29,6 +32,8 @@ import java.security.KeyStore;
public class DefaultSecurityManager implements DBPSecurityManager {
static final Log log = Log.getLog(DefaultSecurityManager.class);
private static final char[] DEFAULT_PASSWORD = "".toCharArray();
public static final String JKS_EXTENSION = ".jks";
private final File localPath;
......@@ -40,12 +45,47 @@ public class DefaultSecurityManager implements DBPSecurityManager {
}
@Override
public KeyStore getKeyStore(String ksId) {
return null;
public KeyStore getKeyStore(String ksId) throws DBException {
try {
File ksFile = getKeyStorePath(ksId);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
if (ksFile.exists()) {
try (InputStream is = new FileInputStream(ksFile)) {
ks.load(is, DEFAULT_PASSWORD);
}
} else {
ks.load(null, DEFAULT_PASSWORD);
}
return ks;
} catch (Exception e) {
throw new DBException("Error opening keystore '" + ksId + "'", e);
}
}
@Override
public void addCertificate(String ksId, String certId, InputStream certStream) throws DBException {
final KeyStore keyStore = getKeyStore(ksId);
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(certStream);
keyStore.setCertificateEntry(certId, cert);
saveKeyStore(ksId, keyStore);
} catch (Exception e) {
throw new DBException("Error adding certificate to keystore '" + ksId + "'", e);
}
}
private void saveKeyStore(String ksId, KeyStore keyStore) throws Exception {
final File ksFile = getKeyStorePath(ksId);
try (OutputStream os = new FileOutputStream(ksFile)) {
keyStore.store(os, DEFAULT_PASSWORD);
}
}
@Override
public File getKeyStorePath(String ksId) {
return null;
return new File(localPath, ksId + JKS_EXTENSION);
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册