summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui
diff options
context:
space:
mode:
authorSimon Rettberg2015-08-18 19:49:30 +0200
committerSimon Rettberg2015-08-18 19:49:30 +0200
commit6e1b0f5a5da9bb8f73ff62166d09647d9d479ad8 (patch)
tree2b8dd3e12f96f2dbd5df8fa7caa1e8c34af06745 /dozentenmodul/src/main/java/org/openslx/dozmod/gui
parent[client] Remove old unused class (diff)
downloadtutor-module-6e1b0f5a5da9bb8f73ff62166d09647d9d479ad8.tar.gz
tutor-module-6e1b0f5a5da9bb8f73ff62166d09647d9d479ad8.tar.xz
tutor-module-6e1b0f5a5da9bb8f73ff62166d09647d9d479ad8.zip
[client] Use TLS to talk to master and satellite
Diffstat (limited to 'dozentenmodul/src/main/java/org/openslx/dozmod/gui')
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/GraphicalCertHandler.java115
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java21
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java25
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java7
4 files changed, 155 insertions, 13 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/GraphicalCertHandler.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/GraphicalCertHandler.java
new file mode 100644
index 00000000..07b44175
--- /dev/null
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/GraphicalCertHandler.java
@@ -0,0 +1,115 @@
+package org.openslx.dozmod.gui;
+
+import java.math.BigInteger;
+import java.security.KeyManagementException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.log4j.Logger;
+import org.openslx.dozmod.authentication.FingerprintManager;
+import org.openslx.dozmod.gui.Gui.GuiCallable;
+import org.openslx.dozmod.gui.helper.MessageType;
+
+public class GraphicalCertHandler {
+
+ private static final Logger LOGGER = Logger.getLogger(GraphicalCertHandler.GuiTrustManager.class);
+
+ private class GuiTrustManager implements X509TrustManager {
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
+ if (certs == null || certs.length == 0) {
+ Gui.asyncMessageBox(
+ "Der Satellit besitzt kein Zertifikat. Verschlüsselte Verbindung nicht möglich.\n\n"
+ + "Möchten Sie trotzdem fortfahren?", MessageType.WARNING, LOGGER, null);
+ // TODO: Ask and do
+ throw new CertificateException("No certificate provided by server");
+ }
+ byte[] encoded = certs[0].getEncoded();
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-256");
+ } catch (NoSuchAlgorithmException e) {
+ LOGGER.warn("Could not get SHA-256 hash of certificate", e);
+ throw new CertificateException("Could not get SHA-256 hash of certificate");
+ }
+ md.update(encoded);
+ byte[] actualFingerprint = md.digest();
+ final String actualFingerprintReadable = new BigInteger(actualFingerprint).toString(16);
+ // Now check the fingerprint
+ byte[] expectedFingerprint = FingerprintManager.getFingerprint(address);
+ final String question;
+ if (expectedFingerprint == null) {
+ // Not known yet, ask
+ question = "Magst du die Zahl " + actualFingerprintReadable + "?";
+ } else if (Arrays.equals(actualFingerprint, expectedFingerprint)) {
+ // Known, matches, everything's fine
+ return;
+ } else {
+ // Known, mismatch, panic!
+ question = "!!! ALARM !!!! ALARM !!! *trage hol*\n\n" + "Der Fingerabdruck von " + address
+ + " hat sich verändert.\n" + "Erwartet: "
+ + new BigInteger(expectedFingerprint).toString(16) + "\n" + "Vorgefunden: "
+ + actualFingerprintReadable + "\n\n"
+ + "Möchten Sie trotzdem zu diesem Satelliten verbinden?";
+ }
+ // Some question needs to be asked
+ Boolean userOk = Gui.syncExec(new GuiCallable<Boolean>() {
+ @Override
+ public Boolean run() {
+ return Gui.showMessageBox(null, question, MessageType.QUESTION_YESNO, null, null);
+ }
+ });
+ if (userOk) {
+ FingerprintManager.saveFingerprint(address, actualFingerprint);
+ } else {
+ throw new CertificateException("Rejected by user");
+ }
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ }
+
+ private final String address;
+
+ private final SSLContext sslContext;
+
+ private GraphicalCertHandler(String address) {
+ SSLContext ctx = null;
+ try {
+ ctx = SSLContext.getInstance("TLSv1.2");
+ } catch (NoSuchAlgorithmException e) {
+ Gui.asyncMessageBox("Could not get TLSv1.2 SSL context", MessageType.ERROR, LOGGER, e);
+ }
+ if (ctx != null) {
+ try {
+ ctx.init(null, new TrustManager[] { new GuiTrustManager() }, null);
+ } catch (KeyManagementException e) {
+ Gui.asyncMessageBox("Could not initialize TLSv1.2 SSL context", MessageType.ERROR, LOGGER, e);
+ ctx = null;
+ }
+ }
+ this.sslContext = ctx;
+ this.address = address;
+ }
+
+ public static SSLContext getSslContext(String address) {
+ return new GraphicalCertHandler(address).sslContext;
+ }
+
+}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
index 0b961461..a40600fe 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
@@ -271,4 +271,25 @@ public class Gui {
return ret == JOptionPane.OK_OPTION || ret == JOptionPane.YES_OPTION;
}
+ /**
+ * Show a message box to the user asynchronously, and optionally log the
+ * message to the log file. This is most useful when working from another
+ * thread.
+ *
+ * @param message Message to display. Can be multi line.
+ * @param messageType Type of message (warning, information)
+ * @param logger Logger instance to log to. Can be null.
+ * @param exception Exception related to this message. Can be null.
+ * @return true if OK or YES was clicked, false for CANCEL/NO/(X)
+ */
+ public static void asyncMessageBox(final String message, final MessageType messageType,
+ final Logger logger, final Throwable exception) {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ showMessageBox(null, message, messageType, logger, exception);
+ }
+ });
+ }
+
}
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
index 2f9fbf50..f8c179b0 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
@@ -64,7 +64,6 @@ public abstract class MainWindow {
private static final List<ActivityPanel> activities = new ArrayList<>();
-
/**
* Set the visible page of the main window.
*
@@ -148,10 +147,10 @@ public abstract class MainWindow {
return Gui.syncExec(new GuiCallable<Boolean>() {
@Override
public Boolean run() {
- return Gui.showMessageBox(mainWindow, "Die Kommunikation mit dem bwLehrpool-Zentralserver ist"
- + " gestört. Der Aufruf der Funktion " + method
- + " ist fehlgeschlagen.\n\n"
- + "Möchten Sie den Aufruf wiederholen?",
+ return Gui.showMessageBox(mainWindow,
+ "Die Kommunikation mit dem bwLehrpool-Zentralserver ist"
+ + " gestört. Der Aufruf der Funktion " + method
+ + " ist fehlgeschlagen.\n\n" + "Möchten Sie den Aufruf wiederholen?",
MessageType.ERROR_RETRY, LOGGER, t);
}
});
@@ -167,10 +166,10 @@ public abstract class MainWindow {
return Gui.syncExec(new GuiCallable<Boolean>() {
@Override
public Boolean run() {
- return Gui.showMessageBox(mainWindow, "Die Kommunikation mit dem Satellitenserver ist"
- + " gestört. Der Aufruf der Funktion " + method
- + " ist fehlgeschlagen.\n\n"
- + "Möchten Sie den Aufruf wiederholen?",
+ return Gui.showMessageBox(mainWindow,
+ "Die Kommunikation mit dem Satellitenserver ist"
+ + " gestört. Der Aufruf der Funktion " + method
+ + " ist fehlgeschlagen.\n\n" + "Möchten Sie den Aufruf wiederholen?",
MessageType.ERROR_RETRY, LOGGER, t);
}
});
@@ -251,10 +250,14 @@ public abstract class MainWindow {
// Wait for proxy server init
App.waitForInit();
try {
- WhoamiInfo whoami = ThriftManager.getNewSatClient(session.address).whoami(session.token);
+ WhoamiInfo whoami = ThriftManager.getNewSatelliteClient(
+ GraphicalCertHandler.getSslContext(session.address), session.address,
+ App.THRIFT_SSL_PORT, App.THRIFT_TIMEOUT_MS).whoami(session.token);
// TODO: Satellite whoami call
Session.initialize(whoami, session.address, session.token, session.masterToken);
- ThriftManager.setSatelliteAddress(Session.getSatelliteAddress());
+ ThriftManager.setSatelliteAddress(
+ GraphicalCertHandler.getSslContext(Session.getSatelliteAddress()),
+ Session.getSatelliteAddress(), App.THRIFT_SSL_PORT, App.THRIFT_TIMEOUT_MS);
LOGGER.info("Saved session used for resume.");
} catch (Exception e1) {
LOGGER.info("Session resume failed.", e1);
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java
index 36b59eed..56a0607c 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java
@@ -32,6 +32,7 @@ import org.openslx.dozmod.authentication.EcpAuthenticator;
import org.openslx.dozmod.authentication.ShibbolethEcp;
import org.openslx.dozmod.authentication.ShibbolethEcp.ReturnCode;
import org.openslx.dozmod.authentication.TestAccountAuthenticator;
+import org.openslx.dozmod.gui.GraphicalCertHandler;
import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
@@ -333,7 +334,8 @@ public class LoginWindow extends LoginWindowLayout {
// TODO: Show satellite selection if > 1
//String satAddress = data.satellites.get(0).addressList.get(0);
String satAddress = "132.230.8.113"; // TODO: HACK HACK
- Client client = ThriftManager.getNewSatClient(satAddress);
+ Client client = ThriftManager.getNewSatelliteClient(GraphicalCertHandler.getSslContext(satAddress), satAddress,
+ App.THRIFT_SSL_PORT, App.THRIFT_TIMEOUT_MS);
if (client == null) {
Gui.showMessageBox(this, "Login erfolgreich, aber der Satellit antwortet nicht",
MessageType.ERROR, LOGGER, null);
@@ -360,7 +362,8 @@ public class LoginWindow extends LoginWindowLayout {
}
if (whoami != null) {
Session.initialize(whoami, satAddress, data.satelliteToken, data.masterToken);
- ThriftManager.setSatelliteAddress(Session.getSatelliteAddress());
+ ThriftManager.setSatelliteAddress(GraphicalCertHandler.getSslContext(Session.getSatelliteAddress()),
+ Session.getSatelliteAddress(), App.THRIFT_SSL_PORT, App.THRIFT_TIMEOUT_MS);
// now read the config to see if the user already agreed to the disclaimer
// if (DisclaimerWindow.shouldBeShown())
// VirtualizerNoticeWindow.open();