2016-10-22 20:21:01 +00:00
|
|
|
package buttondevteam.website;
|
2016-10-22 19:20:28 +00:00
|
|
|
|
2017-06-01 21:33:01 +00:00
|
|
|
import java.io.*;
|
2016-10-22 20:21:01 +00:00
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.net.InetSocketAddress;
|
2017-06-05 20:37:43 +00:00
|
|
|
import java.security.KeyPair;
|
2017-06-01 21:33:01 +00:00
|
|
|
import java.security.KeyStore;
|
|
|
|
import java.security.PrivateKey;
|
2017-06-05 20:37:43 +00:00
|
|
|
import java.security.Security;
|
2017-06-01 21:33:01 +00:00
|
|
|
import java.security.cert.CertificateFactory;
|
|
|
|
import java.util.Calendar;
|
2017-06-13 20:45:07 +00:00
|
|
|
import java.util.concurrent.ArrayBlockingQueue;
|
|
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
2017-06-01 21:33:01 +00:00
|
|
|
|
|
|
|
import javax.net.ssl.*;
|
|
|
|
import java.security.cert.Certificate;
|
2017-05-30 21:24:48 +00:00
|
|
|
|
2017-06-05 20:37:43 +00:00
|
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
|
|
import org.bouncycastle.openssl.PEMKeyPair;
|
|
|
|
import org.bouncycastle.openssl.PEMParser;
|
|
|
|
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
2017-05-30 21:24:48 +00:00
|
|
|
import org.bukkit.Bukkit;
|
2016-10-22 20:21:01 +00:00
|
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
2017-06-01 21:33:01 +00:00
|
|
|
|
|
|
|
import com.sun.net.httpserver.HttpsConfigurator;
|
|
|
|
import com.sun.net.httpserver.HttpsParameters;
|
|
|
|
import com.sun.net.httpserver.HttpsServer;
|
2016-10-22 19:20:28 +00:00
|
|
|
|
2017-05-30 21:24:48 +00:00
|
|
|
import buttondevteam.lib.TBMCCoreAPI;
|
2016-10-22 20:21:01 +00:00
|
|
|
import buttondevteam.website.page.*;
|
|
|
|
|
|
|
|
public class ButtonWebsiteModule extends JavaPlugin {
|
2017-11-23 22:25:56 +00:00
|
|
|
public static final int PORT = 443;
|
2017-06-01 21:33:01 +00:00
|
|
|
private static HttpsServer server;
|
2017-05-30 21:24:48 +00:00
|
|
|
|
2017-05-31 19:09:08 +00:00
|
|
|
public ButtonWebsiteModule() {
|
2016-10-22 20:21:01 +00:00
|
|
|
try {
|
2017-06-01 21:33:01 +00:00
|
|
|
server = HttpsServer.create(new InetSocketAddress((InetAddress) null, PORT), 10);
|
|
|
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
|
|
|
|
|
|
|
// initialise the keystore
|
|
|
|
char[] password = "password".toCharArray();
|
|
|
|
KeyStore ks = KeyStore.getInstance("JKS");
|
|
|
|
String certfile = "domain-chain.crt"; /* your cert path */
|
|
|
|
File keystoreFile = new File("keystore.keystore");
|
|
|
|
|
2017-06-06 05:57:49 +00:00
|
|
|
ks.load(keystoreFile.exists() ? new FileInputStream(keystoreFile) : null, password);
|
2017-06-01 21:33:01 +00:00
|
|
|
|
|
|
|
String alias = "chroma";
|
|
|
|
|
|
|
|
//////
|
|
|
|
|
|
|
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
|
|
|
InputStream certstream = fullStream(certfile);
|
|
|
|
Certificate[] certs = cf.generateCertificates(certstream).stream().toArray(Certificate[]::new);
|
|
|
|
|
2017-06-05 20:37:43 +00:00
|
|
|
BufferedReader br = new BufferedReader(new FileReader("domain.key"));
|
2017-06-01 21:33:01 +00:00
|
|
|
|
2017-06-05 20:37:43 +00:00
|
|
|
Security.addProvider(new BouncyCastleProvider());
|
|
|
|
|
|
|
|
PEMParser pp = new PEMParser(br);
|
|
|
|
PEMKeyPair pemKeyPair = (PEMKeyPair) pp.readObject();
|
|
|
|
KeyPair kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
|
|
|
|
pp.close();
|
|
|
|
PrivateKey pk = kp.getPrivate();
|
2017-06-01 21:33:01 +00:00
|
|
|
|
|
|
|
// Add the certificate
|
|
|
|
ks.setKeyEntry(alias, pk, password, certs); // TODO: Only set if updated
|
|
|
|
|
|
|
|
// Save the new keystore contents
|
|
|
|
FileOutputStream out = new FileOutputStream(keystoreFile);
|
|
|
|
ks.store(out, password);
|
|
|
|
out.close();
|
|
|
|
|
|
|
|
// setup the key manager factory
|
|
|
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
|
|
|
|
kmf.init(ks, password);
|
|
|
|
|
|
|
|
// setup the trust manager factory
|
|
|
|
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
|
|
|
|
tmf.init(ks);
|
|
|
|
|
|
|
|
// setup the HTTPS context and parameters
|
|
|
|
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
|
|
|
|
server.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
|
|
|
|
public void configure(HttpsParameters params) {
|
|
|
|
try {
|
|
|
|
// initialise the SSL context
|
|
|
|
SSLContext c = SSLContext.getDefault();
|
|
|
|
SSLEngine engine = c.createSSLEngine();
|
|
|
|
params.setNeedClientAuth(false);
|
|
|
|
params.setCipherSuites(engine.getEnabledCipherSuites());
|
|
|
|
params.setProtocols(engine.getEnabledProtocols());
|
|
|
|
|
|
|
|
// get the default parameters
|
|
|
|
SSLParameters defaultSSLParameters = c.getDefaultSSLParameters();
|
|
|
|
params.setSSLParameters(defaultSSLParameters);
|
|
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
System.out.println("Failed to create HTTPS port");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2016-10-22 20:21:01 +00:00
|
|
|
} catch (Exception e) {
|
2017-05-30 21:24:48 +00:00
|
|
|
TBMCCoreAPI.SendException("An error occured while starting the webserver!", e);
|
2017-06-05 20:37:43 +00:00
|
|
|
getServer().getPluginManager().disablePlugin(this);
|
2016-10-22 20:21:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 19:09:08 +00:00
|
|
|
@Override
|
|
|
|
public void onEnable() {
|
|
|
|
addPage(new IndexPage());
|
2017-11-23 22:25:56 +00:00
|
|
|
addPage(new LoginPage());
|
|
|
|
addPage(new ProfilePage());
|
2017-06-30 21:58:36 +00:00
|
|
|
addPage(new BuildNotificationsPage());
|
2017-06-15 20:12:02 +00:00
|
|
|
TBMCCoreAPI.RegisterUserClass(WebUser.class);
|
2017-05-31 19:09:08 +00:00
|
|
|
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
|
|
|
|
this.getLogger().info("Starting webserver...");
|
2017-06-13 20:45:07 +00:00
|
|
|
server.setExecutor(
|
|
|
|
new ThreadPoolExecutor(4, 8, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100)));
|
2017-06-01 21:33:01 +00:00
|
|
|
final Calendar calendar = Calendar.getInstance();
|
2017-06-16 21:46:10 +00:00
|
|
|
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY && !TBMCCoreAPI.IsTestServer()) { // Only update every week
|
2017-11-23 22:25:56 +00:00
|
|
|
addPage(new AcmeChallengePage()); // Add before the server gets started
|
2017-06-01 21:33:01 +00:00
|
|
|
Thread t = new Thread(() -> AcmeClient.main("server.figytuna.com"));
|
|
|
|
t.setContextClassLoader(getClass().getClassLoader());
|
|
|
|
t.start();
|
|
|
|
}
|
2017-11-23 22:25:56 +00:00
|
|
|
((Runnable) server::start).run(); // Totally normal way of calling a method
|
|
|
|
this.getLogger().info("Webserver started");
|
2017-05-31 19:09:08 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-05-30 21:24:48 +00:00
|
|
|
/**
|
|
|
|
* Adds a new page/endpoint to the website. This method needs to be called before the server finishes loading (onEnable).
|
|
|
|
*/
|
|
|
|
public static void addPage(Page page) {
|
2016-10-22 20:21:01 +00:00
|
|
|
server.createContext("/" + page.GetName(), page);
|
|
|
|
}
|
2017-06-01 21:33:01 +00:00
|
|
|
|
|
|
|
private static InputStream fullStream(String fname) throws IOException {
|
|
|
|
FileInputStream fis = new FileInputStream(fname);
|
|
|
|
DataInputStream dis = new DataInputStream(fis);
|
|
|
|
byte[] bytes = new byte[dis.available()];
|
|
|
|
dis.readFully(bytes);
|
|
|
|
dis.close();
|
|
|
|
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
|
|
|
return bais;
|
|
|
|
}
|
2016-10-22 19:20:28 +00:00
|
|
|
}
|