diff options
-rw-r--r-- | dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java | 211 | ||||
-rw-r--r-- | dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java | 2 |
2 files changed, 127 insertions, 86 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java index 5841efc5..5d14f3fc 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/configurator/NetrulesConfigurator.java @@ -2,19 +2,16 @@ package org.openslx.dozmod.gui.configurator; import java.awt.Color; import java.awt.Insets; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Set; import javax.swing.BorderFactory; +import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextPane; @@ -24,7 +21,10 @@ import javax.swing.event.ChangeListener; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.Style; import javax.swing.text.StyleConstants; +import javax.swing.text.TabSet; +import javax.swing.text.TabStop; import org.apache.log4j.Logger; import org.openslx.bwlp.thrift.iface.NetDirection; @@ -74,6 +74,7 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements @Override public void changed() { checkChange = true; + fireChangeEvent(); } }; final SimpleAttributeSet as = new SimpleAttributeSet(); @@ -114,12 +115,10 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements }); } }); - tpNetworkRules.addFocusListener(new FocusAdapter() { + btnCheckRules.addActionListener(new ActionListener() { @Override - public void focusLost(FocusEvent e) { - if (checkChange) { - fireChangeEvent(); - } + public void actionPerformed(ActionEvent e) { + getState(false); } }); } @@ -228,7 +227,6 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements } StringBuilder errors = new StringBuilder(); // Error messages to show (if not silent) int lineNo = 0; // Show line numbers in error messages - Set<String> warnedHosts = new HashSet<>(); // Ask only once about each unknown host for (String ruleLine : rawNetRules.split("[\r\n]+")) { if (silent && invalid) return null; @@ -281,43 +279,21 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements // is resolvable. If any of these happen, we have a valid hostname. // Non-resolvable hostnames are handled differently, see after the // try/catch-block - InetAddress ruleHost = null; - try { - // TODO: Find a way to reliably set a timeout (external DNS library?) - // Otherwise just remove this check - ruleHost = InetAddress.getByName(fields[0]); - } catch (UnknownHostException e) { - // might be good to see this exception in the log file - // LOGGER.debug("Invalid hostname (java.net): ", e); - } - if (ruleHost == null) { - // either invalid IP-Address or an invalid resolvable hostname - // however it might also be a non-resolvable hostname that would - // be valid in the actual pool-rooms, so lets check its syntax - // according to: http://tools.ietf.org/html/rfc1034#section-3.1 - LOGGER.debug("Invalid host/IP! Got: " + fields[0]); - String checkRes = checkHostnameSimple(fields[0]); - if (checkRes == null) { - if (!silent - && !warnedHosts.contains(fields[0]) - && !Gui.showMessageBox("Konnte '" + fields[0] - + "' nicht auflösen. Wollen Sie diesen Hostnamen trotzdem verwenden?", - MessageType.WARNING_RETRY, null, null)) { - invalid = true; - } - warnedHosts.add(fields[0]); - lineColor = Color.ORANGE; - } else { - lineNo += addLine(newdoc, ruleLine, Color.RED, true); - errors.append("Zeile " + lineNo + ": " + checkRes + "\n"); - invalid = true; - continue; - } + String checkRes = checkHostnameSimple(fields[0]); + if (checkRes != null) { + lineNo += addLine(newdoc, ruleLine, Color.RED, true); + errors.append("Zeile " + lineNo + ": " + checkRes + "\n"); + invalid = true; + continue; } // Made it to here - line is valid lineNo += addLine(newdoc, ruleLine, lineColor, false); rulesList.add(new NetRule(NetDirection.valueOf(ruleDirection), fields[0], port)); } + if (newdoc != null) { + tpNetworkRules.setDocument(newdoc); + resetTabStops(); + } if (!silent && errors.length() != 0) { Gui.showMessageBox("Fehler beim Auswerten der angegebenen Netzwerkregeln.\n\n" + errors.toString() + "\nBitte geben Sie die Regeln zeilenweise im Format\n" @@ -325,9 +301,6 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements + "an.", MessageType.ERROR, null, null); } - if (newdoc != null) { - tpNetworkRules.setDocument(newdoc); - } if (invalid) { return null; } @@ -364,25 +337,84 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements * @param hostname the hostname to check for syntactical validity * @return null if valid, error string otherwise */ - private String checkHostnameSimple(final String hostname) { + private String checkHostnameSimple(String hostname) { if (hostname.length() > 254) { return "Hostname ist zu lang."; } - // split by '.' to get domain levels boolean allNumeric = true; - String[] domainLabels = hostname.split("\\."); - for (String domainLabel : domainLabels) { - if (domainLabel.length() > 63) { - // fail since domain level should be max 63 chars - return "Domain-Ebene '" + domainLabel + "' länger als 63 Zeichen."; + int netmask = -1; + String[] domainLabels = null; + int ls = hostname.lastIndexOf('/'); + if (ls != -1) { + netmask = Util.parseInt(hostname.substring(ls + 1), -1); + if (netmask == -1) { + return "Ungültige Netzmaske."; } - if (Util.parseInt(domainLabel, -1) == -1) { - allNumeric = false; - } - // checking for valid chars is pointless with punycode + hostname = hostname.substring(0, ls); } - if (allNumeric && domainLabels.length != 4) { - return "Unvollständige IP-Adresse."; + if (hostname.matches("^\\[.*\\]$")) { + hostname = hostname.substring(1, hostname.length() - 2); + } else { + // split by '.' to get domain levels + domainLabels = hostname.split("\\."); + } + if (domainLabels == null || (domainLabels.length <= 1 && hostname.indexOf(':') != -1)) { + // v6 + if ((hostname.startsWith(":") && !hostname.startsWith("::")) + || (hostname.endsWith(":") && ! hostname.endsWith("::"))) { + return "IPv6-Adresse darf nicht mit einem Doppelpunkt beginnen oder enden."; + } + int numCompressed = (hostname.length() - hostname.replace("::", "").length()) / 2; + if (numCompressed > 1) { + return "IPv6-Adresse darf nicht mehr als einen komprimierten Teil enthalten."; + } + if (netmask > 128) { + return "IPv6 Netzmaske kann nicht größer 128 Bit sein."; + } + domainLabels = hostname.split(":"); + if (domainLabels.length > 8) { + return "IPv6-Adresse enthält zu viele Hextets."; // Yes it's called that apparently + } + for (String domainLabel : domainLabels) { + if (domainLabel.isEmpty()) + continue; + try { + int test = Integer.parseInt(domainLabel, 16); + if (test < 0 || test > 65535) { + return "IPv6-Adresse enthält ungültiges Hextet."; + } + } catch (Exception e) { + return "IPv6-Adresse enthält nicht-hexadezimale Zeichen."; + } + } + if (!allNumeric + || ((domainLabels.length == 8 || numCompressed > 0) && (netmask < -1 || netmask > 128)) + || (domainLabels.length < 8 && numCompressed == 0 && (netmask < 0 || netmask > 128))) { + return "Fehlerhafte IPv6-Adresse/Netzmaske."; + } + } else { + // v4 or hostname + if (netmask > 32) { + return "IPv4 Netzmaske kann nicht größer 32 Bit sein."; + } + for (String domainLabel : domainLabels) { + if (domainLabel.length() > 63) { + // fail since domain level should be max 63 chars + return "Domain-Ebene '" + domainLabel + "' länger als 63 Zeichen."; + } + int i = Util.parseInt(domainLabel, -1); + if (i < 0 || i > 255) { + allNumeric = false; + } + // checking for valid chars is pointless with punycode + } + if (allNumeric) { + if ((domainLabels.length == 4 && (netmask < -1 || netmask > 32)) + || domainLabels.length > 4 + || (domainLabels.length < 4 && (netmask < 0 || netmask > 32))) { + return "Fehlerhafte IPv4-Adresse/Netzmaske."; + } + } } return null; } @@ -395,45 +427,54 @@ public class NetrulesConfigurator extends NetrulesConfiguratorLayout implements class NetrulesConfiguratorLayout extends JPanel { private static final long serialVersionUID = 5266120380443817325L; - private final static String txtNetworkOptionsTitle = "Netzwerk Einstellungen"; - private final static String txtNetworkOptionsDesc = "Wenn Sie den Internetzugriff deaktiviert haben," + private final static String STR_RULES_DESCRIPTION = "Wenn Sie den Internetzugriff deaktiviert haben," + " können Sie hier Ausnahmen definieren (Whitelist)." + " Bitte definieren Sie Ihre Regeln im Format\n<host> <port> <in|out>.\n" - + "Sie können Port 0 angeben, was sämtlichen TCP und UDP Ports eines Hosts entspricht.\n\n" - + "Wenn Sie Internetzugriff aktivieren, hat diese Liste den gegenteiligen Effekt"; - private final static String txtNetworkRulesTitle = "Netzwerkregeln"; + + "Sie können Port 0 angeben, was sämtlichen TCP und UDP Ports eines Hosts entspricht."; + private final static String STR_RULES_ADD = "Wenn Sie Internetzugriff aktivieren," + + " hat diese Liste den gegenteiligen Effekt (Blacklist)."; + private final static String STR_TITLE = "Netzwerkregeln"; - private final JPanel pnlNetworkOptions; protected final JTextPane tpNetworkRules; + protected final JButton btnCheckRules; public NetrulesConfiguratorLayout() { - GridManager grid = new GridManager(this, 1, true, + GridManager grid = new GridManager(this, 2, true, new Insets(5, 5, 5, 5)); // middle panel for network rules - pnlNetworkOptions = new JPanel(); - GridManager gridNetworkOptions = new GridManager(pnlNetworkOptions, 1, - true, new Insets(2, 2, 2, 2)); - pnlNetworkOptions.setBorder(BorderFactory - .createTitledBorder(txtNetworkOptionsTitle)); + this.setBorder(BorderFactory.createTitledBorder(STR_TITLE)); tpNetworkRules = new JTextPane(); + resetTabStops(); - JScrollPane scpNetworkRules = new JScrollPane(tpNetworkRules, - JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - pnlNetworkOptions.setBorder(BorderFactory - .createTitledBorder(txtNetworkRulesTitle)); - gridNetworkOptions - .add(new WordWrapLabel(txtNetworkOptionsDesc)) + grid + .add(new WordWrapLabel(STR_RULES_DESCRIPTION), 2) + .fill(true, false).expand(true, false); + grid.nextRow(); + + grid + .add(new WordWrapLabel(STR_RULES_ADD)) .fill(true, false).expand(true, false); - gridNetworkOptions.nextRow(); - gridNetworkOptions.add(scpNetworkRules).fill(true, true) - .expand(true, true); - gridNetworkOptions.finish(false); + btnCheckRules = new JButton("Regeln überprüfen"); + grid.add(btnCheckRules); + grid.nextRow(); + + grid.add(new JScrollPane(tpNetworkRules, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), 2) + .fill(true, true).expand(true, true); + grid.nextRow(); - // build the final grid - grid.add(pnlNetworkOptions).fill(true, true).expand(true, true); grid.finish(false); } + + protected void resetTabStops() { + Style tabs = tpNetworkRules.getLogicalStyle(); + StyleConstants.setTabSet(tabs, new TabSet(new TabStop[] { + new TabStop(300, TabStop.ALIGN_RIGHT, TabStop.LEAD_NONE), + new TabStop(310, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE), + })); + tpNetworkRules.setLogicalStyle(tabs); + } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java index ac94333b..9fc5dd34 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LectureDetailsWindow.java @@ -534,7 +534,7 @@ public class LectureDetailsWindow extends LectureDetailsWindowLayout implements ctlLocationSelector.getOnlyInSelection(), // TODO limitOnlyToAllowedUsers, default to false for now false, chkHasUsbAccess.isSelected()); - metadata.setNetworkExceptions(ctlNetrulesConfigurator.getState(false)); + metadata.setNetworkExceptions(ctlNetrulesConfigurator.getState()); metadata.setNetworkShares(ctlNetshareConfigurator.getState()); metadata.setLdapFilters(ctlLdapFilterConfigurator.getState()); |