Fixed certificate handling
This commit is contained in:
parent
e8270d4027
commit
d9ce3af5aa
6 changed files with 84 additions and 25 deletions
0
gradlew
vendored
Executable file → Normal file
0
gradlew
vendored
Executable file → Normal 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_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_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_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 CONFIG_MAP_BACKGROUND_IMAGE = "hal_core.map_bgimage";
|
||||||
|
|
||||||
public static final String RESOURCE_ROOT;
|
public static final String RESOURCE_ROOT;
|
||||||
|
|
@ -104,10 +105,10 @@ public class HalContext {
|
||||||
registerProperty(key);
|
registerProperty(key);
|
||||||
|
|
||||||
String value = null;
|
String value = null;
|
||||||
if (dbConf != null)
|
|
||||||
value = dbConf.getProperty(key);
|
|
||||||
if (fileConf != null)
|
if (fileConf != null)
|
||||||
value = fileConf.getProperty(key);
|
value = fileConf.getProperty(key);
|
||||||
|
if (value == null && dbConf != null)
|
||||||
|
value = dbConf.getProperty(key);
|
||||||
return value != null ? value : defaultValue;
|
return value != null ? value : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,7 +117,7 @@ public class HalContext {
|
||||||
}
|
}
|
||||||
public static int getIntegerProperty(String key, int defaultValue){
|
public static int getIntegerProperty(String key, int defaultValue){
|
||||||
String value = getStringProperty(key);
|
String value = getStringProperty(key);
|
||||||
return value != null ? getIntegerProperty(key) : defaultValue;
|
return value != null ? Integer.parseInt(getStringProperty(key)) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getBooleanProperty(String key) {
|
public static boolean getBooleanProperty(String key) {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,10 @@ import se.hal.util.HalAcmeDataStore;
|
||||||
import zutil.db.DBConnection;
|
import zutil.db.DBConnection;
|
||||||
import zutil.io.file.FileUtil;
|
import zutil.io.file.FileUtil;
|
||||||
import zutil.log.LogUtil;
|
import zutil.log.LogUtil;
|
||||||
|
import zutil.net.acme.AcmeChallengeFactory;
|
||||||
import zutil.net.acme.AcmeClient;
|
import zutil.net.acme.AcmeClient;
|
||||||
|
import zutil.net.acme.AcmeHttpChallengeFactory;
|
||||||
|
import zutil.net.acme.AcmeManualDnsChallengeFactory;
|
||||||
import zutil.net.http.HttpPage;
|
import zutil.net.http.HttpPage;
|
||||||
import zutil.net.http.HttpServer;
|
import zutil.net.http.HttpServer;
|
||||||
import zutil.net.http.page.HttpFilePage;
|
import zutil.net.http.page.HttpFilePage;
|
||||||
|
|
@ -79,16 +82,35 @@ public class HalServer {
|
||||||
|
|
||||||
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT) &&
|
if (HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_PORT) &&
|
||||||
HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN)) {
|
HalContext.containsProperty(CONFIG_HTTP_EXTERNAL_DOMAIN)) {
|
||||||
// Start a non secure server to retrieve handle the ACME protocol challenge
|
AcmeClient acme;
|
||||||
HttpServer tmpHttpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT));
|
HttpServer tmpHttpServer = null;
|
||||||
tmpHttpExternal.start();
|
|
||||||
|
|
||||||
AcmeClient acme = new AcmeClient(new HalAcmeDataStore());
|
if ("dns".equals(HalContext.getStringProperty(HalContext.CONFIG_HTTP_EXTERNAL_ACME_TYPE, ""))) {
|
||||||
Certificate certificate = acme.fetchCertificate(tmpHttpExternal, HalContext.getStringProperty(CONFIG_HTTP_EXTERNAL_DOMAIN));
|
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();
|
acme = new AcmeClient(new HalAcmeDataStore(), new AcmeHttpChallengeFactory(tmpHttpServer), AcmeClient.ACME_SERVER_LETSENCRYPT_STAGING);
|
||||||
httpExternal = new HttpServer(HalContext.getIntegerProperty(CONFIG_HTTP_EXTERNAL_PORT));
|
} 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();
|
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 {
|
} else {
|
||||||
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
|
logger.warning("Missing '" + CONFIG_HTTP_EXTERNAL_PORT + "' and '" + CONFIG_HTTP_EXTERNAL_DOMAIN + "' configuration, will not setup external http server.");
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,66 @@
|
||||||
package se.hal.util;
|
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.net.acme.AcmeDataStore;
|
||||||
|
import zutil.parser.Base64Decoder;
|
||||||
|
import zutil.parser.Base64Encoder;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class HalAcmeDataStore implements AcmeDataStore {
|
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_USER_KEY = "hal_core.http_external_user_key";
|
||||||
private static final String CONFIG_HTTP_EXTERNAL_DOMAIN_KEY = "hal_core.http_external_domain_key";
|
private static final String CONFIG_HTTP_EXTERNAL_DOMAIN_KEY = "hal_core.http_external_domain_key";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyPair loadUserKeyPair() {
|
public KeyPair loadUserKeyPair() {
|
||||||
return null;
|
return loadKeyPair(CONFIG_HTTP_EXTERNAL_USER_KEY);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storeUserKeyPair(KeyPair keyPair) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyPair loadDomainKeyPair() {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeUserKeyPair(KeyPair keyPair) {
|
||||||
|
storeKeyPair(keyPair, CONFIG_HTTP_EXTERNAL_USER_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeDomainKeyPair(KeyPair keyPair) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
|
||||||
public static final int PROTOCOL_VERSION = 5; // Increment for protocol changes
|
public static final int PROTOCOL_VERSION = 5; // Increment for protocol changes
|
||||||
|
|
||||||
|
|
||||||
public PCDataSynchronizationDaemon() {
|
public PCDataSynchronizationDaemon() throws IOException {
|
||||||
super(HalContext.getIntegerProperty(PROPERTY_SYNC_PORT));
|
super(HalContext.getIntegerProperty(PROPERTY_SYNC_PORT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,20 +81,20 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
|
||||||
|
|
||||||
|
|
||||||
private class DataSynchronizationDaemonThread implements ThreadedTCPNetworkServerThread{
|
private class DataSynchronizationDaemonThread implements ThreadedTCPNetworkServerThread{
|
||||||
private Socket s;
|
private Socket socket;
|
||||||
private ObjectOutputStream out;
|
private ObjectOutputStream out;
|
||||||
private ObjectInputStream in;
|
private ObjectInputStream in;
|
||||||
|
|
||||||
|
|
||||||
public DataSynchronizationDaemonThread(Socket s) throws IOException{
|
public DataSynchronizationDaemonThread(Socket socket) throws IOException{
|
||||||
this.s = s;
|
this.socket = socket;
|
||||||
this.out = new ObjectOutputStream(s.getOutputStream());
|
this.out = new ObjectOutputStream(socket.getOutputStream());
|
||||||
this.in = new ObjectInputStream(s.getInputStream());
|
this.in = new ObjectInputStream(socket.getInputStream());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void run(){
|
public void run(){
|
||||||
logger.fine("User connected: "+ s.getInetAddress().getHostName());
|
logger.fine("User connected: "+ socket.getInetAddress().getHostName());
|
||||||
DBConnection db = HalContext.getDB();
|
DBConnection db = HalContext.getDB();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -166,12 +166,12 @@ public class PCDataSynchronizationDaemon extends ThreadedTCPNetworkServer implem
|
||||||
}
|
}
|
||||||
out.close();
|
out.close();
|
||||||
in.close();
|
in.close();
|
||||||
s.close();
|
socket.close();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, null, 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
0
run.sh
Executable file → Normal file
Loading…
Add table
Add a link
Reference in a new issue