Skip to content

Commit

Permalink
feat: support pg ssl
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron3S committed Sep 11, 2024
1 parent f750494 commit 9c40e29
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.jumpserver.chen.framework.driver.DriverClassLoader;
import org.jumpserver.chen.framework.driver.DriverManager;
import org.jumpserver.chen.framework.i18n.MessageUtils;
import org.jumpserver.chen.framework.ssl.JKSGenerator;

import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
Expand Down Expand Up @@ -50,32 +49,7 @@ public void ping(String jdbcUrl) throws SQLException {
this.ping(jdbcUrl, props);
}

protected void setSSLProps(Properties props) {
if (this.getConnectInfo().getOptions().get("useSSL") != null
&& (boolean) this.getConnectInfo().getOptions().get("useSSL")) {
props.setProperty("useSSL", "true");
props.setProperty("requireSSL", "true");
var jksGenerator = new JKSGenerator();
if ((boolean) this.getConnectInfo().getOptions().get("verifyServerCertificate")) {
props.setProperty("verifyServerCertificate", "true");
jksGenerator.setCaCert((String) this.getConnectInfo().getOptions().get("caCert"));

var caCertPath = jksGenerator.generateCaJKS();
props.setProperty("trustCertificateKeyStoreUrl", "file:" + caCertPath);
props.setProperty("trustCertificateKeyStorePassword", JKSGenerator.JSK_PASS);

}
if (StringUtils.isNotBlank((String) this.getConnectInfo().getOptions().get("clientCert"))) {
jksGenerator.setClientCert((String) this.getConnectInfo().getOptions().get("clientCert"));
jksGenerator.setClientKey((String) this.getConnectInfo().getOptions().get("clientKey"));
var clientCertPath = jksGenerator.generateClientJKS();
props.setProperty("clientCertificateKeyStoreUrl", "file:" + clientCertPath);
props.setProperty("clientCertificateKeyStorePassword", JKSGenerator.JSK_PASS);
props.setProperty("clientKeyPassword", JKSGenerator.JSK_PASS);

}
}
}
protected void setSSLProps(Properties props) {}


public List<DriverClassLoader> getDriverClassLoaders() {
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.jumpserver.chen.framework.ssl;
package org.jumpserver.chen.modules.base.ssl;

import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.jumpserver.chen.modules.base.ssl;

import lombok.Setter;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;

public class SSLCertManager {

@Setter
private String caCert; // CA 证书
@Setter
private String clientCertKey; // 客户端私钥
@Setter
private String clientCert; // 客户端证书


private File caCertFile;
private File clientCertKeyFile;
private File clientCertFile;

// 获取 CA 证书的路径
private String getCaCertPath() throws IOException {
if (caCertFile == null) {
caCertFile = createTempFile("ca-cert", caCert);
}
return caCertFile.getAbsolutePath();
}

// 获取客户端私钥的路径
private String getClientCertKeyPath() throws IOException {
if (clientCertKeyFile == null) {
clientCertKeyFile = createTempFile("client-cert-key", clientCertKey);
}
return clientCertKeyFile.getAbsolutePath();
}

// 获取客户端证书的路径
private String getClientCertPath() throws IOException {
if (clientCertFile == null) {
clientCertFile = createTempFile("client-cert", clientCert);
}
return clientCertFile.getAbsolutePath();
}

// 销毁资源,如果 autoDestroy 为 true,则删除临时文件
public void Destroy() {
deleteTempFile(caCertFile);
deleteTempFile(clientCertKeyFile);
deleteTempFile(clientCertFile);
}

// 辅助方法:创建临时文件并写入内容
private File createTempFile(String prefix, String content) throws IOException {
File tempFile = File.createTempFile(prefix, ".pem");
try (FileWriter writer = new FileWriter(tempFile)) {
writer.write(content);
}
tempFile.deleteOnExit(); // JVM 退出时自动删除
return tempFile;
}

// 辅助方法:删除临时文件
private void deleteTempFile(File file) {
if (file != null && file.exists()) {
try {
Files.delete(file.toPath());
System.out.println("Deleted file: " + file.getAbsolutePath());
} catch (IOException e) {
System.err.println("Failed to delete file: " + file.getAbsolutePath());
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package org.jumpserver.chen.modules.mysql;

import org.apache.commons.lang3.StringUtils;
import org.jumpserver.chen.framework.datasource.Datasource;
import org.jumpserver.chen.framework.datasource.base.BaseConnectionManager;
import org.jumpserver.chen.framework.datasource.entity.DBConnectInfo;
import org.jumpserver.chen.framework.datasource.sql.SQL;
import org.jumpserver.chen.modules.base.ssl.JKSGenerator;

import java.sql.SQLException;
import java.util.Properties;

public class MysqlConnectionManager extends BaseConnectionManager {

Expand All @@ -29,6 +32,35 @@ public void ping() throws SQLException {
this.jdbcUrl = url;
}


protected void setSSLProps(Properties props) {
if (this.getConnectInfo().getOptions().get("useSSL") != null
&& (boolean) this.getConnectInfo().getOptions().get("useSSL")) {

props.setProperty("useSSL", "true");
props.setProperty("requireSSL", "true");

var jksGenerator = new JKSGenerator();
if ((boolean) this.getConnectInfo().getOptions().get("verifyServerCertificate")) {
props.setProperty("verifyServerCertificate", "true");
jksGenerator.setCaCert((String) this.getConnectInfo().getOptions().get("caCert"));

var caCertPath = jksGenerator.generateCaJKS();
props.setProperty("trustCertificateKeyStoreUrl", "file:" + caCertPath);
props.setProperty("trustCertificateKeyStorePassword", JKSGenerator.JSK_PASS);

}
if (StringUtils.isNotBlank((String) this.getConnectInfo().getOptions().get("clientCert"))) {
jksGenerator.setClientCert((String) this.getConnectInfo().getOptions().get("clientCert"));
jksGenerator.setClientKey((String) this.getConnectInfo().getOptions().get("clientKey"));
var clientCertPath = jksGenerator.generateClientJKS();
props.setProperty("clientCertificateKeyStoreUrl", "file:" + clientCertPath);
props.setProperty("clientCertificateKeyStorePassword", JKSGenerator.JSK_PASS);
props.setProperty("clientKeyPassword", JKSGenerator.JSK_PASS);
}
}
}

@Override
public String getVersion() throws SQLException {
var result = this.sqlActuator.execute(SQL.of("select version()"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.jumpserver.chen.framework.datasource.sql.SQL;

import java.sql.SQLException;
import java.util.Properties;

public class PostgresqlConnectionManager extends BaseConnectionManager {

Expand All @@ -30,6 +31,22 @@ public void ping() throws SQLException {
this.jdbcUrl = url;
}

protected void setSSLProps(Properties props) {
if (this.getConnectInfo().getOptions().get("useSSL") != null
&& (boolean) this.getConnectInfo().getOptions().get("useSSL")) {

var caCertPath = (String) this.getConnectInfo().getOptions().get("caCert");
var clientCertPath = (String) this.getConnectInfo().getOptions().get("clientCert");
var clientKeyPath = (String) this.getConnectInfo().getOptions().get("clientKey");

props.setProperty("ssl", "true");
props.setProperty("sslmode", "verify-full");
props.setProperty("sslrootcert", caCertPath);
props.setProperty("sslcert", clientCertPath);
props.setProperty("sslkey", clientKeyPath);
}
}

private static final String SQL_GET_VERSION = "SELECT version()";

@Override
Expand Down
2 changes: 1 addition & 1 deletion backend/modules/src/test/java/mysql/TestMysqlDriver.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package mysql;

import com.alibaba.druid.pool.DruidDataSource;
import org.jumpserver.chen.framework.ssl.JKSGenerator;
import org.jumpserver.chen.modules.base.ssl.JKSGenerator;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
Expand Down

0 comments on commit 9c40e29

Please sign in to comment.