Fixed certificate handling

This commit is contained in:
Ziver Koc 2021-08-20 23:10:13 +02:00
parent e8270d4027
commit d9ce3af5aa
6 changed files with 84 additions and 25 deletions

0
gradlew vendored Executable file → Normal file
View file

View file

@ -24,6 +24,7 @@ public class HalContext {
public static final String CONFIG_HTTP_PORT = "hal_core.http_port";
public static final String CONFIG_HTTP_EXTERNAL_PORT = "hal_core.http_external_port";
public static final String CONFIG_HTTP_EXTERNAL_DOMAIN = "hal_core.http_external_domain";
public static final String CONFIG_HTTP_EXTERNAL_ACME_TYPE = "hal_core.http_external_acme_type";
public static final String CONFIG_MAP_BACKGROUND_IMAGE = "hal_core.map_bgimage";
public static final String RESOURCE_ROOT;
@ -104,10 +105,10 @@ public class HalContext {
registerProperty(key);
String value = null;
if (dbConf != null)
value = dbConf.getProperty(key);
if (fileConf != null)
value = fileConf.getProperty(key);
if (value == null && dbConf != null)
value = dbConf.getProperty(key);
return value != null ? value : defaultValue;
}
@ -116,7 +117,7 @@ public class HalContext {
}
public static int getIntegerProperty(String key, int defaultValue){
String value = getStringProperty(key);
return value != null ? getIntegerProperty(key) : defaultValue;
return value != null ? Integer.parseInt(getStringProperty(key)) : defaultValue;
}
public static boolean getBooleanProperty(String key) {

View file

@ -8,7 +8,10 @@ import se.hal.util.HalAcmeDataStore;
import zutil.db.DBConnection;
import zutil.io.file.FileUtil;
import zutil.log.LogUtil;
import zutil.net.acme.AcmeChallengeFactory;
import zutil.net.acme.AcmeClient;
import zutil.net.acme.AcmeHttpChallengeFactory;
import zutil.net.acme.AcmeManualDnsChallengeFactory;
import zutil.net.http.HttpPage;
import zutil.net.http.HttpServer;
import zutil.net.http.page.HttpFilePage;
@ -79,16 +82,35 @@ public class HalServer {
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT) &&
HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN)) {
// Start a non secure server to retrieve handle the ACME protocol challenge
HttpServer tmpHttpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT));
tmpHttpExternal.start();
AcmeClient acme;
HttpServer tmpHttpServer = null;
AcmeClient acme = new AcmeClient(new HalAcmeDataStore());
Certificate certificate = acme.fetchCertificate(tmpHttpExternal, HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
if ("dns".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, ""))) {
acme = new AcmeClient(new HalAcmeDataStore(), new AcmeManualDnsChallengeFactory(), AcmeClient.ACME_SERVER_LETSENCRYPT_STAGING);
} else if ("http".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, "http"))) {
tmpHttpServer = new HttpServer(80);
tmpHttpServer.start();
tmpHttpExternal.close();
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT));
acme = new AcmeClient(new HalAcmeDataStore(), new AcmeHttpChallengeFactory(tmpHttpServer), AcmeClient.ACME_SERVER_LETSENCRYPT_STAGING);
} else {
throw new IllegalArgumentException("Unknown config value for " + HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE + ": " +
HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE));
}
acme.addDomain(HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
acme.prepareRequest();
Certificate certificate = acme.requestCertificate();
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT), certificate);
httpExternal.start();
// Cleanup
if ("http".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, "http"))) {
tmpHttpServer.close();
}
logger.info("External https server up and running at: https://" + HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN) + ":" + HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT));
} else {
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
return;

View file

@ -1,30 +1,66 @@
package se.hal.util;
import org.shredzone.acme4j.util.KeyPairUtils;
import se.hal.HalContext;
import zutil.log.LogUtil;
import zutil.net.acme.AcmeDataStore;
import zutil.parser.Base64Decoder;
import zutil.parser.Base64Encoder;
import java.io.*;
import java.security.KeyPair;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HalAcmeDataStore implements AcmeDataStore {
private static final Logger logger = LogUtil.getLogger();
private static final String CONFIG_HTTP_EXTERNAL_USER_KEY = "hal_core.http_external_user_key";
private static final String CONFIG_HTTP_EXTERNAL_DOMAIN_KEY = "hal_core.http_external_domain_key";
@Override
public KeyPair loadUserKeyPair() {
return null;
}
@Override
public void storeUserKeyPair(KeyPair keyPair) {
return loadKeyPair(CONFIG_HTTP_EXTERNAL_USER_KEY);
}
@Override
public KeyPair loadDomainKeyPair() {
return loadKeyPair(CONFIG_HTTP_EXTERNAL_DOMAIN_KEY);
}
private KeyPair loadKeyPair(String configName) {
if (HalContext.containsProperty(configName)) {
try {
byte[] data = Base64Decoder.decodeToByte(
HalContext.getStringProperty(configName));
return KeyPairUtils.readKeyPair(new InputStreamReader(new ByteArrayInputStream(data)));
} catch (IOException e) {
logger.log(Level.SEVERE, "Was unable to load KeyPair from DB.", e);
}
}
return null;
}
@Override
public void storeUserKeyPair(KeyPair keyPair) {
storeKeyPair(keyPair, CONFIG_HTTP_EXTERNAL_USER_KEY);
}
@Override
public void storeDomainKeyPair(KeyPair keyPair) {
storeKeyPair(keyPair, CONFIG_HTTP_EXTERNAL_DOMAIN_KEY);
}
private void storeKeyPair(KeyPair keyPair, String configName) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out);
KeyPairUtils.writeKeyPair(keyPair, writer);
HalContext.setProperty(configName, Base64Encoder.encode(out.toByteArray()));
} catch (IOException e) {
logger.log(Level.SEVERE, "Was unable to store KeyPair to DB.", e);
}
}
}

View file

@ -58,7 +58,7 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
public static final int PROTOCOL_VERSION = 5; // Increment for protocol changes
public PCDataSynchronizationDaemon() {
public PCDataSynchronizationDaemon() throws IOException {
super(HalContext.getIntegerProperty(PROPERTY_SYNC_PORT));
}
@ -81,20 +81,20 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
private class DataSynchronizationDaemonThread implements ThreadedTCPNetworkServerThread{
private Socket s;
private Socket socket;
private ObjectOutputStream out;
private ObjectInputStream in;
public DataSynchronizationDaemonThread(Socket s) throws IOException{
this.s = s;
this.out = new ObjectOutputStream(s.getOutputStream());
this.in = new ObjectInputStream(s.getInputStream());
public DataSynchronizationDaemonThread(Socket socket) throws IOException{
this.socket = socket;
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
}
public void run(){
logger.fine("User connected: "+ s.getInetAddress().getHostName());
logger.fine("User connected: "+ socket.getInetAddress().getHostName());
DBConnection db = HalContext.getDB();
try {
@ -166,12 +166,12 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
}
out.close();
in.close();
s.close();
socket.close();
} catch (Exception e) {
logger.log(Level.SEVERE, null, e);
}
logger.fine("User disconnected: "+ s.getInetAddress().getHostName());
logger.fine("User disconnected: "+ socket.getInetAddress().getHostName());
}
}

0
run.sh Executable file → Normal file
View file