Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server whitelist #685

Merged
merged 38 commits into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
a8844ab
wildcards in whitelist - first cut
janakmulani Jul 14, 2020
1bd391e
wildcards in whitelist - first cut
janakmulani Jul 14, 2020
aff17f9
wildcards in whitelist - first cut
janakmulani Jul 14, 2020
5e7ea85
pass expanded wildcard urls to isUrlInWhiteList
janakmulani Jul 16, 2020
889476c
expand whitelist only once
janakmulani Jul 16, 2020
e99f714
Merge remote-tracking branch 'adopt/master' into server_whitelist_wil…
janakmulani Jul 16, 2020
6151d49
server whitelist panel and refactor
janakmulani Jul 22, 2020
6d6a987
new warning icon
janakmulani Jul 24, 2020
e216355
modify table look
janakmulani Jul 29, 2020
bc4d687
Merge branch 'master' into server_whitelist_wildcard
janakmulani Jul 29, 2020
048070a
remove test code
janakmulani Jul 31, 2020
1f59103
remove import
janakmulani Jul 31, 2020
aff8cb0
remove unused methods
janakmulani Jul 31, 2020
5ad47d0
final method params
janakmulani Jul 31, 2020
564610a
remove unused tests
janakmulani Jul 31, 2020
4db334b
refactored
janakmulani Aug 6, 2020
709f763
Merge pull request #674 from janakmulani/server_whitelist_wildcard
sclassen Aug 6, 2020
d76736a
Merge branch 'master' into serverWhitelist
sclassen Aug 6, 2020
b008bc9
move whitelist to new package
sclassen Aug 6, 2020
9b44de7
cleanup java warnings
sclassen Aug 6, 2020
f21cfad
rename method
sclassen Aug 6, 2020
137f86c
cleanup java warnings
sclassen Aug 6, 2020
4521038
inline param which was always true
sclassen Aug 6, 2020
b53de73
convert WhitelistEntry to top level class
sclassen Aug 6, 2020
dc639e0
move matching logic into WhitelistEntry
sclassen Aug 6, 2020
3e06072
rename WhitelistEntry properties
sclassen Aug 6, 2020
bc585f5
parse effective whitelist URL in static factory method
sclassen Aug 6, 2020
c036294
reorder methods
sclassen Aug 6, 2020
ba83c43
assert not null only in entry method (public method)
sclassen Aug 6, 2020
7c3af41
cleanup test code
sclassen Aug 7, 2020
4ee2162
Merge pull request #686 from AdoptOpenJDK/improveServerWhitelist
sclassen Aug 7, 2020
0216986
move logic to WhitelistEntryState
sclassen Aug 7, 2020
9ac968d
add more tests
sclassen Aug 7, 2020
e8b73e2
re-use background functionality from DefaultTableCellRenderer
sclassen Aug 10, 2020
2ee8eaa
convert anonymous inner class -> EffectiveWhitelistCellRenderer
sclassen Aug 10, 2020
a27df00
add exception message
sclassen Aug 10, 2020
29771d4
make methods non static to avoid passing field of same class around
sclassen Aug 10, 2020
9fdc3bd
set default values in constructor
sclassen Aug 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,13 @@ CPInvalidPort=Invalid port number given.\n[Valid port numbers are 1-65535]
CPInvalidPortTitle=Error on input.

# Control Panel - ServerwhitelistPanel
SWPInvalidURL=Server not in whitelist.
SWPInvalidURL=Server URL not in whitelist.
SWPCol0Header=Specified Whitelist
SWPCol1Header=Validated Whitelist
SWPVALIDATEHOST=* allowed only in host''s first part and as only character.
SWPVALIDATEIPHOST=* not allowed in IP address.
SWPINVALIDIPHOST=Invalid IP address.
SWPINVALIDWLURL=Invalid Whitelist Url.

# command line control panel
CLNoInfo=No information available (is this a valid option?).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,13 @@ CPInvalidPort=Ung\u00FCltige Anschlussnummer eingegeben.\n[G\u00FCltige Anschlus
CPInvalidPortTitle=Eingabefehler

# Control Panel - ServerwhitelistPanel
SWPInvalidURL=Server nicht in Whitelist.
SWPInvalidURL=Server URL nicht in Whitelist.
SWPCol0Header=Angegebene Whitelist
SWPCol1Header=Validierte Whitelist
SWPVALIDATEHOST=* Nur im ersten Teil des Hosts und als einziges Zeichen zul\u00E4ssig.
SWPVALIDATEIPHOST=* in IP-Adresse nicht zul\u00E4ssig.
SWPINVALIDIPHOST=Ung\u00FCltige IP-Adresse.
SWPINVALIDWLURL=Ung\u00FCltige Whitelist-URL.

# command line control panel
CLNoInfo=Keine Informationen verf\u00FCgbar (ist dies eine g\u00FCltige Option?).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
Expand Down Expand Up @@ -231,6 +232,7 @@ private JPanel createMainSettingsPanel(final ControlPanelStyle style) {


final JList<String> settingsList = new JList<>(panels.keySet().toArray(new String[0]));
settingsList.setFont(new Font(settingsList.getFont().getName(), Font.BOLD, settingsList.getFont().getSize()));
settingsList.addListSelectionListener(e -> cardLayout.show(settingsPanel, settingsList.getSelectedValue()));
settingsList.setSelectedIndex(0);
DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,34 @@
import net.adoptopenjdk.icedteaweb.Assert;
import net.adoptopenjdk.icedteaweb.client.controlpanel.NamedBorderPanel;
import net.adoptopenjdk.icedteaweb.i18n.Translator;
import net.adoptopenjdk.icedteaweb.jdk89access.SunMiscLauncher;
import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils;
import net.sourceforge.jnlp.util.whitelist.WhitelistEntry;

import javax.swing.JList;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.List;
import java.util.Vector;

import static net.sourceforge.jnlp.config.ConfigurationConstants.KEY_SECURITY_SERVER_WHITELIST;
import static net.adoptopenjdk.icedteaweb.i18n.Translator.R;

/**
* This provides a way for the user to display the server white list defined in <code>deployment.properties</code>.
*/
@SuppressWarnings("serial")
public class ServerWhitelistPanel extends NamedBorderPanel {

private static final ImageIcon WARNING_ICON = SunMiscLauncher.getSecureImageIcon("net/sourceforge/jnlp/resources/warn16.png");

/**
* This creates a new instance of the server white list panel.
*
Expand All @@ -46,9 +58,92 @@ public ServerWhitelistPanel(final DeploymentConfiguration config) {

Assert.requireNonNull(config, "config");

final List<String> whitelist = config.getPropertyAsList(KEY_SECURITY_SERVER_WHITELIST);
final JList<String> jList = new JList<>(new Vector<>(whitelist));
jList.setFixedCellHeight(20);
add(new JScrollPane(jList), BorderLayout.CENTER);
final List<WhitelistEntry> whitelist = UrlWhiteListUtils.getApplicationUrlWhiteList();

final JTable table = new JTable(createTableModel(whitelist));
table.getTableHeader().setReorderingAllowed(false);
table.setFillsViewportHeight(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
table.setAutoCreateRowSorter(true);

final TableColumnModel colModel = table.getColumnModel();
colModel.getColumn(0).setPreferredWidth(100);
colModel.getColumn(1).setPreferredWidth(250);

final DefaultTableCellRenderer cellRenderer = new EffectiveWhitelistCellRenderer();
table.getColumnModel().getColumn(1).setCellRenderer(cellRenderer);
cellRenderer.setIconTextGap(5);
sclassen marked this conversation as resolved.
Show resolved Hide resolved
cellRenderer.setVerticalTextPosition(SwingConstants.CENTER);
sclassen marked this conversation as resolved.
Show resolved Hide resolved
final JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
add(scrollPane, BorderLayout.CENTER);
}

private TableModel createTableModel(final List<WhitelistEntry> whitelist) {
final String[] colNames = {R("SWPCol0Header"), R("SWPCol1Header")};
return new AbstractTableModel() {
@Override
public int getRowCount() {
return whitelist.size();
}

public String getColumnName(int col) {
return colNames[col];
}

@Override
public int getColumnCount() {
return colNames.length;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
WhitelistEntry whitelistEntry = whitelist.get(rowIndex);
switch (columnIndex) {
case 0:
return whitelistEntry.getRawWhitelistEntry();
case 1:
return new WhitelistEntryState(whitelistEntry);
default:
throw new IllegalArgumentException("column index > 1 - this should not happen");
}
}
};
}

private static class WhitelistEntryState {
private final WhitelistEntry entry;

public WhitelistEntryState(WhitelistEntry entry) {
this.entry = entry;
}

public boolean isValid() {
return entry.isValid();
}

public String getMessage() {
return isValid() ? entry.getEffectiveWhitelistEntry() : R("SWPINVALIDWLURL") + ": " + entry.getErrorMessage();
}
}

private static class EffectiveWhitelistCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
final WhitelistEntryState wleState = (WhitelistEntryState) value;
if (wleState != null) {
setText(wleState.getMessage());
if (!wleState.isValid()) {
setIcon(WARNING_ICON);
} else {
setIcon(null);
}
} else {
setText(null);
setIcon(null);
}
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@


import net.adoptopenjdk.icedteaweb.Assert;
import net.adoptopenjdk.icedteaweb.StringUtils;
import net.adoptopenjdk.icedteaweb.client.BasicExceptionDialog;
import net.adoptopenjdk.icedteaweb.i18n.Translator;
import net.adoptopenjdk.icedteaweb.logging.Logger;
Expand All @@ -12,19 +11,16 @@
import net.adoptopenjdk.icedteaweb.resources.initializer.ResourceInitializer;
import net.sourceforge.jnlp.cache.CacheUtil;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import net.sourceforge.jnlp.util.IpUtil;
import net.sourceforge.jnlp.util.whitelist.UrlWhiteListUtils;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static net.adoptopenjdk.icedteaweb.resources.Resource.Status.DOWNLOADED;
import static net.adoptopenjdk.icedteaweb.resources.Resource.Status.ERROR;
import static net.sourceforge.jnlp.config.ConfigurationConstants.KEY_SECURITY_SERVER_WHITELIST;
import static net.sourceforge.jnlp.util.UrlUtils.FILE_PROTOCOL;
import static net.sourceforge.jnlp.util.UrlUtils.decodeUrlQuietly;

Expand Down Expand Up @@ -125,22 +121,10 @@ private void validateWithWhitelist() {
final URL url = resource.getLocation();
Assert.requireNonNull(url, "url");

final List<String> whitelist = JNLPRuntime.getConfiguration().getPropertyAsList(KEY_SECURITY_SERVER_WHITELIST)
.stream().filter(s -> !StringUtils.isBlank(s)).collect(Collectors.toList());

if (whitelist.isEmpty()) {
return; // empty whitelist == allow all connections
}

// if host is null or "" or it is localhost or loopback
if (IpUtil.isLocalhostOrLoopback(url)) {
return; // local server need not be in whitelist
}

final String urlString = url.getProtocol() + "://" + url.getHost() + ((url.getPort() != -1) ? ":" + url.getPort() : "");

if (!whitelist.contains(urlString)) {
BasicExceptionDialog.show(new SecurityException(Translator.R("SWPInvalidURL") + ": " + resource.getLocation()));
// Validate with whitelist specified in deployment.properties. localhost is considered valid.
final boolean found = UrlWhiteListUtils.isUrlInApplicationUrlWhitelist(url);
if (!found) {
BasicExceptionDialog.show(new SecurityException(Translator.R("SWPInvalidURL") + ": " + url));
LOG.error("Resource URL not In Whitelist: {}", resource.getLocation());
JNLPRuntime.exit(-1);
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/java/net/sourceforge/jnlp/util/IpUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import java.net.URL;

public class IpUtil {
public static boolean isLocalhostOrLoopback(URL url) {
public static boolean isLocalhostOrLoopback(final URL url) {
return isLocalhostOrLoopback(url.getHost());
}

public static boolean isLocalhostOrLoopback(URI uri) {
public static boolean isLocalhostOrLoopback(final URI uri) {
return isLocalhostOrLoopback(uri.getHost());
}

Expand All @@ -20,7 +20,7 @@ public static boolean isLocalhostOrLoopback(URI uri) {
* @return true if the given host string is blank or represents or resolves to the hostname or the IP address
* of localhost or the loopback address.
*/
static boolean isLocalhostOrLoopback(String host) {
static boolean isLocalhostOrLoopback(final String host) {
if (StringUtils.isBlank(host)) {
return true; // java.net.InetAddress.getByName(host).isLoopbackAddress() returns true
}
Expand Down
Loading