aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java')
-rw-r--r--src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java96
1 files changed, 94 insertions, 2 deletions
diff --git a/src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java b/src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java
index f4e64f6..86deda9 100644
--- a/src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java
+++ b/src/main/java/de/cowtipper/cowlection/config/CredentialStorage.java
@@ -4,8 +4,23 @@ import de.cowtipper.cowlection.Cowlection;
import de.cowtipper.cowlection.util.ApiUtils;
import de.cowtipper.cowlection.util.Utils;
import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.MathHelper;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
+import org.apache.http.conn.ssl.SSLContexts;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.util.Enumeration;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Key and secret holder in its own file to avoid people leaking their keys accidentally.
@@ -13,6 +28,7 @@ import net.minecraftforge.common.config.Property;
public class CredentialStorage {
public static String moo;
public static boolean isMooValid;
+ public static SSLContext sslContext;
private Property propMoo;
private Property propIsMooValid;
private final Configuration cfg;
@@ -20,17 +36,18 @@ public class CredentialStorage {
public CredentialStorage(Configuration configuration) {
cfg = configuration;
initConfig();
+ verifyNewerHttpsSupport();
}
private void initConfig() {
cfg.load();
propMoo = cfg.get(Configuration.CATEGORY_CLIENT,
- "moo", "", "Don't share this with anybody! Do not edit this entry manually either!", Utils.VALID_UUID_PATTERN)
+ "moo", "", "Don't share this with anybody! Do not edit this entry manually either!", Utils.VALID_UUID_PATTERN)
.setShowInGui(false);
propMoo.setLanguageKey(Cowlection.MODID + ".config." + propMoo.getName());
propIsMooValid = cfg.get(Configuration.CATEGORY_CLIENT,
- "isMooValid", false, "Is the value valid?")
+ "isMooValid", false, "Is the value valid?")
.setShowInGui(false);
moo = propMoo.getString();
isMooValid = propIsMooValid.getBoolean();
@@ -39,6 +56,81 @@ public class CredentialStorage {
}
}
+ private void verifyNewerHttpsSupport() {
+ String javaVersion = System.getProperty("java.version", "unknown java version");
+ Pattern javaVersionPattern = Pattern.compile("1\\.8\\.0_(\\d+)"); // e.g. 1.8.0_51
+ Matcher javaVersionMatcher = javaVersionPattern.matcher(javaVersion);
+ if (!javaVersionMatcher.matches()
+ || MathHelper.parseIntWithDefault(javaVersionMatcher.group(1), 1337) >= 101) {
+ // newer Java version (>=8u101): *should* already have support by default
+ return;
+ }
+
+ // running Java <8u101
+ if (testNewHttps()) {
+ // uhm... looks like someone added the certs to the default JKS already
+ return;
+ }
+ System.out.println("Injecting Let's Encrypt support due to ancient Java version...");
+ try {
+ KeyStore originalKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ originalKeyStore.load(Files.newInputStream(Paths.get(System.getProperty("java.home"), "lib", "security", "cacerts")), "changeit".toCharArray());
+
+ KeyStore mooKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ mooKeyStore.load(getClass().getResourceAsStream("/https-for-ancient-java.jks"), "mooveit".toCharArray());
+
+ KeyStore tempKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ tempKeyStore.load(null, "moovedit".toCharArray());
+
+ for (Enumeration<String> aliases = originalKeyStore.aliases(); aliases.hasMoreElements(); ) {
+ String alias = aliases.nextElement();
+ tempKeyStore.setCertificateEntry(alias, originalKeyStore.getCertificate(alias));
+ }
+ for (Enumeration<String> aliases = mooKeyStore.aliases(); aliases.hasMoreElements(); ) {
+ String alias = aliases.nextElement();
+ tempKeyStore.setCertificateEntry(alias, mooKeyStore.getCertificate(alias));
+ }
+ sslContext = SSLContexts.custom()
+ .loadKeyMaterial(tempKeyStore, "moovedit".toCharArray())
+ .loadTrustMaterial(tempKeyStore, null)
+ .build();
+
+ if (!testNewHttps()) {
+ System.err.println("Error while trying to add Let's Encrypt support: Could not contact site after running setup");
+ }
+ } catch (GeneralSecurityException | IOException e) {
+ System.err.println("Error while trying to add Let's Encrypt support:");
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Tests accessing a site that uses Let's Encrypt
+ *
+ * @return true, if connection was successful
+ */
+ private boolean testNewHttps() {
+ try {
+ URLConnection connection = new URL("https://helloworld.letsencrypt.org/").openConnection();
+ connection.setConnectTimeout(5000);
+ connection.setReadTimeout(8000);
+ connection.setDoInput(false);
+ connection.setDoOutput(false);
+ connection.addRequestProperty("User-Agent", "Forge Mod " + Cowlection.MODNAME + "/" + Cowlection.VERSION + " (" + Cowlection.GITURL + ")");
+ if (CredentialStorage.sslContext != null && connection instanceof HttpsURLConnection) {
+ ((HttpsURLConnection) connection).setSSLSocketFactory(CredentialStorage.sslContext.getSocketFactory());
+ }
+
+ connection.connect();
+
+ // seems to be working since there was no IOException!
+ return true;
+ } catch (IOException ignored) {
+ // most likely a newer https related issue, so setup might fix things
+ }
+ return false;
+ }
+
public void setMooIfValid(String moo, boolean commandTriggered) {
ApiUtils.fetchApiKeyInfo(moo, hyApiKey -> {
if (hyApiKey != null && hyApiKey.isSuccess()) {