summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-08-17 18:14:08 +0200
committerSimon Rettberg2015-08-17 18:14:08 +0200
commit76f13bf7a26b79b0f4a45ec7992c4bcd8eeb9ee6 (patch)
tree172aa0259d6172f9881e3c02b84b0bdf58bb890c
parent[server] Switch to libthrift 0.9.2 (diff)
downloadtutor-module-76f13bf7a26b79b0f4a45ec7992c4bcd8eeb9ee6.tar.gz
tutor-module-76f13bf7a26b79b0f4a45ec7992c4bcd8eeb9ee6.tar.xz
tutor-module-76f13bf7a26b79b0f4a45ec7992c4bcd8eeb9ee6.zip
[server] Add TLS/SSL related classes and functionality (wip)
-rw-r--r--dozentenmodulserver/setup/sat-01-schema.sql6
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java17
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbConfiguration.java83
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java15
-rw-r--r--dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java43
5 files changed, 154 insertions, 10 deletions
diff --git a/dozentenmodulserver/setup/sat-01-schema.sql b/dozentenmodulserver/setup/sat-01-schema.sql
index 2919ff8a..6c517530 100644
--- a/dozentenmodulserver/setup/sat-01-schema.sql
+++ b/dozentenmodulserver/setup/sat-01-schema.sql
@@ -189,6 +189,12 @@ CREATE TABLE IF NOT EXISTS `lectureuser` (
PRIMARY KEY (`lectureid`, `userlogin`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+CREATE TABLE IF NOT EXISTS `configuration` (
+ `parameter` varchar(100) CHARACTER SET ascii NOT NULL,
+ `value` blob NOT NULL,
+ PRIMARY KEY (`parameter`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
ALTER TABLE `lectureuser`
ADD CONSTRAINT `fk_lectureuser_1` FOREIGN KEY (`lectureid`) REFERENCES `sat`.`lecture` (`lectureid`) ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
index 5ceb72cc..e7d0b9aa 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/App.java
@@ -1,5 +1,6 @@
package org.openslx.bwlp.sat;
+import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -16,6 +17,7 @@ import org.openslx.bwlp.sat.thrift.BinaryListener;
import org.openslx.bwlp.sat.thrift.cache.OperatingSystemList;
import org.openslx.bwlp.sat.thrift.cache.OrganizationList;
import org.openslx.bwlp.sat.util.Configuration;
+import org.openslx.bwlp.sat.util.Identity;
import org.openslx.bwlp.sat.util.Json;
import org.openslx.bwlp.thrift.iface.ImageSummaryRead;
import org.openslx.bwlp.thrift.iface.NetDirection;
@@ -34,7 +36,7 @@ public class App {
public static boolean DEBUG = false;
- public static void main(String[] args) throws TTransportException, NoSuchAlgorithmException {
+ public static void main(String[] args) throws TTransportException, NoSuchAlgorithmException, IOException {
//get going and show basic information in log file
BasicConfigurator.configure();
if (args.length != 0 && args[0].equals("debug")) {
@@ -53,6 +55,11 @@ public class App {
System.exit(1);
}
+ if (Identity.loadCertificate() == null) {
+ LOGGER.error("Could not set up TLS/SSL requirements, exiting");
+ System.exit(1);
+ }
+
ThriftManager.setErrorCallback(new ErrorCallback() {
@Override
@@ -81,11 +88,16 @@ public class App {
LOGGER.error("Could not start internal file server.");
return;
}
- // Start Server
+ // Start Thrift Server
Thread t;
+ // Plain
t = new Thread(new BinaryListener(9090, false));
servers.add(t);
t.start();
+ // SSL
+ t = new Thread(new BinaryListener(9091, true));
+ servers.add(t);
+ t.start();
// DEBUG
if (DEBUG) {
Database.printCharsetInformation();
@@ -124,5 +136,4 @@ public class App {
QuickTimer.cancel();
LOGGER.info(new Date() + " - all Servers shut down, exiting...\n");
}
-
}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbConfiguration.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbConfiguration.java
new file mode 100644
index 00000000..27dc2b6e
--- /dev/null
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/database/mappers/DbConfiguration.java
@@ -0,0 +1,83 @@
+package org.openslx.bwlp.sat.database.mappers;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.openslx.bwlp.sat.database.Database;
+import org.openslx.bwlp.sat.database.MysqlConnection;
+import org.openslx.bwlp.sat.database.MysqlStatement;
+
+public class DbConfiguration {
+
+ private static final Logger LOGGER = Logger.getLogger(DbConfiguration.class);
+
+ private static final String KEY_CERTIFICATE = "certstore";
+
+ public static KeyStore loadKeyStore(String password) throws KeyStoreException, SQLException,
+ NoSuchAlgorithmException, CertificateException, IOException {
+ KeyStore keystore = KeyStore.getInstance("JKS");
+ InputStream stream = retrieveStream(KEY_CERTIFICATE);
+ if (stream == null)
+ return null;
+ keystore.load(stream, password.toCharArray());
+ return keystore;
+ }
+
+ public static void saveKeyStore(File file) throws SQLException, FileNotFoundException, IOException {
+ store(KEY_CERTIFICATE, new FileInputStream(file));
+ }
+
+ private static void store(String configKey, InputStream stream) throws IOException, SQLException {
+ store(configKey, IOUtils.toByteArray(stream));
+ }
+
+ private static void store(String configKey, byte[] value) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("INSERT INTO configuration"
+ + " (parameter, value) VALUES (:parameter, :value)"
+ + " ON DUPLICATE KEY UPDATE value = VALUES(value)");
+ stmt.setString("parameter", configKey);
+ stmt.setBinary("value", value);
+ stmt.executeUpdate();
+ connection.commit();
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbConfiguration.store()", e);
+ throw e;
+ }
+ }
+
+ private static InputStream retrieveStream(String configKey) throws SQLException {
+ byte[] data = retrieve(configKey);
+ if (data == null)
+ return null;
+ return new ByteArrayInputStream(data);
+ }
+
+ private static byte[] retrieve(String configKey) throws SQLException {
+ try (MysqlConnection connection = Database.getConnection()) {
+ MysqlStatement stmt = connection.prepareStatement("SELECT value FROM configuration"
+ + " WHERE parameter = :parameter LIMIT 1");
+ stmt.setString("parameter", configKey);
+ ResultSet rs = stmt.executeQuery();
+ if (!rs.next())
+ return null;
+ return rs.getBytes("value");
+ } catch (SQLException e) {
+ LOGGER.error("Query failed in DbConfiguration.retrieve()", e);
+ throw e;
+ }
+ }
+
+}
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
index f1746697..3232374e 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/fileserv/FileServer.java
@@ -13,11 +13,14 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLContext;
+
import org.apache.log4j.Logger;
import org.openslx.bwlp.sat.database.models.LocalImageVersion;
import org.openslx.bwlp.sat.util.Configuration;
import org.openslx.bwlp.sat.util.Constants;
import org.openslx.bwlp.sat.util.Formatter;
+import org.openslx.bwlp.sat.util.Identity;
import org.openslx.bwlp.thrift.iface.ImageDetailsRead;
import org.openslx.bwlp.thrift.iface.TTransferRejectedException;
import org.openslx.bwlp.thrift.iface.UserInfo;
@@ -35,6 +38,8 @@ public class FileServer implements IncomingEvent {
*/
private final Listener plainListener = new Listener(this, null, 9092, Constants.TRANSFER_TIMEOUT); // TODO: Config
+ private final Listener sslListener;
+
private final ThreadPoolExecutor transferPool = new ThreadPoolExecutor(2, Constants.MAX_UPLOADS
+ Constants.MAX_DOWNLOADS, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1));
@@ -51,6 +56,8 @@ public class FileServer implements IncomingEvent {
private static final FileServer globalInstance = new FileServer();
private FileServer() {
+ SSLContext ctx = Identity.getSSLContext();
+ sslListener = ctx == null ? null : new Listener(this, ctx, 9093, Constants.TRANSFER_TIMEOUT);
}
public static FileServer instance() {
@@ -59,7 +66,9 @@ public class FileServer implements IncomingEvent {
public boolean start() {
boolean ret = plainListener.start();
- // TODO: Start SSL listener too
+ if (sslListener != null) {
+ ret |= sslListener.start();
+ }
return ret;
}
@@ -146,7 +155,9 @@ public class FileServer implements IncomingEvent {
}
public int getSslPort() {
- return 0; // TODO
+ if (sslListener == null)
+ return 0;
+ return sslListener.getPort();
}
public ActiveDownload createNewUserDownload(LocalImageVersion localImageData)
diff --git a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java
index 3e0159b6..b00a8bc3 100644
--- a/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java
+++ b/dozentenmodulserver/src/main/java/org/openslx/bwlp/sat/thrift/BinaryListener.java
@@ -1,14 +1,26 @@
package org.openslx.bwlp.sat.thrift;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
import java.security.NoSuchAlgorithmException;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocketFactory;
import org.apache.log4j.Logger;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
+import org.apache.thrift.server.TThreadPoolServer;
+import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
+import org.apache.thrift.transport.TServerSocket;
+import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportException;
+import org.openslx.bwlp.sat.util.Identity;
import org.openslx.bwlp.thrift.iface.SatelliteServer;
import org.openslx.thrifthelper.TBinaryProtocolSafe;
@@ -17,7 +29,7 @@ public class BinaryListener implements Runnable {
private static final int MAX_MSG_LEN = 30 * 1000 * 1000;
private static final int MINWORKERTHREADS = 2;
- private static final int MAXWORKERTHREADS = 64;
+ private static final int MAXWORKERTHREADS = 96;
private final SatelliteServer.Processor<ServerHandler> processor = new SatelliteServer.Processor<ServerHandler>(
new ServerHandler());
@@ -25,7 +37,8 @@ public class BinaryListener implements Runnable {
private final TServer server;
- public BinaryListener(int port, boolean secure) throws TTransportException, NoSuchAlgorithmException {
+ public BinaryListener(int port, boolean secure) throws TTransportException, NoSuchAlgorithmException,
+ IOException {
if (secure)
server = initSecure(port);
else
@@ -40,9 +53,29 @@ public class BinaryListener implements Runnable {
// TODO: Restart listener; if it fails, quit server so it will be restarted by the OS
}
- private TServer initSecure(int port) throws NoSuchAlgorithmException, TTransportException {
- // TODO
- return null;
+ private TServer initSecure(int port) throws NoSuchAlgorithmException, TTransportException, IOException {
+ SSLContext context = Identity.getSSLContext();
+ if (context == null)
+ return null;
+ SSLServerSocketFactory sslServerSocketFactory = context.getServerSocketFactory();
+ ServerSocket listenSocket = sslServerSocketFactory.createServerSocket();
+ listenSocket.setReuseAddress(true);
+ listenSocket.bind(new InetSocketAddress(port));
+
+ TServerTransport serverTransport;
+ try {
+ serverTransport = new TServerSocket(listenSocket);
+ } catch (TTransportException e) {
+ log.fatal("Could not listen on port " + port);
+ throw e;
+ }
+ TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport);
+ args.protocolFactory(protFactory);
+ args.processor(processor);
+ args.minWorkerThreads(MINWORKERTHREADS).maxWorkerThreads(MAXWORKERTHREADS);
+ args.requestTimeout(2).requestTimeoutUnit(TimeUnit.MINUTES);
+ args.transportFactory(new TFramedTransport.Factory(MAX_MSG_LEN));
+ return new TThreadPoolServer(args);
}
private TServer initNormal(int port) throws TTransportException {