Mercurial > hg > release > icedtea-web-1.0
changeset 45:dd77da50a226
integrate basic proxy configuration support
2010-11-23 Omair Majid <omajid@redhat.com>
* netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java:
Add KEY_PROXY_TYPE, KEY_PROXY_SAME, KEY_PROXY_AUTO_CONFIG_URL,
KEY_PROXY_BYPASS_LIST, KEY_PROXY_BYPASS_LOCAL, KEY_PROXY_HTTP_HOST,
KEY_PROXY_HTTP_PORT, KEY_PROXY_HTTPS_HOST, KEY_PROXY_HTTPS_PORT,
KEY_PROXY_FTP_HOST, KEY_PROXY_FTP_PORT, KEY_PROXY_SOCKS4_HOST,
KEY_PROXY_SOCKS4_PORT, and KEY_PROXY_OVERRIDE_HOSTS.
(loadDefaultProperties): Use the new constants.
* netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java: New
class.
(JNLPProxySelector): New method.
(parseConfiguration): New method. Initializes this object by
querying the configuration.
(getHost): New method.
(getPort): New method.
(connectFailed): New method.
(select): New method. Returns a list of appropriate proxies to use
for a given uri.
(inBypassList): New method. Return true if the host in the URI
should be bypassed for proxy purposes.
(isLocalHost): New method.
(getFromConfiguration): New method. Finds a proxy based on
configuration.
(getFromPAC): New method.
(getFromBrowser): New method.
* netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java
(initialize): Install proxy selector and authenticator.
* plugin/icedteanp/java/sun/applet/PluginMain.java
(init): Do not install authenticator.
(CustomAuthenticator): Moved to...
* netx/net/sourceforge/jnlp/security/JNLPAuthenticator.java: Here.
* plugin/icedteanp/java/sun/applet/PasswordAuthenticationDialog.java
Moved to...
* netx/net/sourceforge/jnlp/security
/PasswordAuthenticationDialog.java: Here.
* plugin/icedteanp/java/sun/applet/PluginProxySelector.java: Extend
JNLPProxySelector.
(select): Renamed to...
(getFromBrowser): New method.
author | Omair Majid <omajid@redhat.com> |
---|---|
date | Tue, 23 Nov 2010 10:05:06 -0500 |
parents | 5a9f55d67b50 |
children | e1400d406d85 |
files | ChangeLog netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java netx/net/sourceforge/jnlp/security/JNLPAuthenticator.java netx/net/sourceforge/jnlp/security/PasswordAuthenticationDialog.java plugin/icedteanp/java/sun/applet/PasswordAuthenticationDialog.java plugin/icedteanp/java/sun/applet/PluginMain.java plugin/icedteanp/java/sun/applet/PluginProxySelector.java |
diffstat | 9 files changed, 755 insertions(+), 296 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Nov 19 10:35:27 2010 -0500 +++ b/ChangeLog Tue Nov 23 10:05:06 2010 -0500 @@ -1,3 +1,44 @@ +2010-11-23 Omair Majid <omajid@redhat.com> + + * netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java: + Add KEY_PROXY_TYPE, KEY_PROXY_SAME, KEY_PROXY_AUTO_CONFIG_URL, + KEY_PROXY_BYPASS_LIST, KEY_PROXY_BYPASS_LOCAL, KEY_PROXY_HTTP_HOST, + KEY_PROXY_HTTP_PORT, KEY_PROXY_HTTPS_HOST, KEY_PROXY_HTTPS_PORT, + KEY_PROXY_FTP_HOST, KEY_PROXY_FTP_PORT, KEY_PROXY_SOCKS4_HOST, + KEY_PROXY_SOCKS4_PORT, and KEY_PROXY_OVERRIDE_HOSTS. + (loadDefaultProperties): Use the new constants. + * netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java: New + class. + (JNLPProxySelector): New method. + (parseConfiguration): New method. Initializes this object by + querying the configuration. + (getHost): New method. + (getPort): New method. + (connectFailed): New method. + (select): New method. Returns a list of appropriate proxies to use + for a given uri. + (inBypassList): New method. Return true if the host in the URI + should be bypassed for proxy purposes. + (isLocalHost): New method. + (getFromConfiguration): New method. Finds a proxy based on + configuration. + (getFromPAC): New method. + (getFromBrowser): New method. + * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java + (initialize): Install proxy selector and authenticator. + * plugin/icedteanp/java/sun/applet/PluginMain.java + (init): Do not install authenticator. + (CustomAuthenticator): Moved to... + * netx/net/sourceforge/jnlp/security/JNLPAuthenticator.java: Here. + * plugin/icedteanp/java/sun/applet/PasswordAuthenticationDialog.java + Moved to... + * netx/net/sourceforge/jnlp/security + /PasswordAuthenticationDialog.java: Here. + * plugin/icedteanp/java/sun/applet/PluginProxySelector.java: Extend + JNLPProxySelector. + (select): Renamed to... + (getFromBrowser): New method. + 2010-11-19 Omair Majid <omajid@redhat.com> * Makefile.am (EXTRA_DIST): Replace javaws.desktop with
--- a/netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java Fri Nov 19 10:35:27 2010 -0500 +++ b/netx/net/sourceforge/jnlp/runtime/DeploymentConfiguration.java Tue Nov 23 10:05:06 2010 -0500 @@ -120,13 +120,6 @@ public static final String CONSOLE_SHOW = "SHOW"; public static final String CONSOLE_DISABLE = "DISABLE"; - /* FIXME these should be moved into the proxy class */ - public static final int PROXY_TYPE_UNKNOWN = -1; - public static final int PROXY_TYPE_NONE = 0; - public static final int PROXY_TYPE_MANUAL = 1; - public static final int PROXY_TYPE_AUTO = 2; - public static final int PROXY_TYPE_BROWSER = 3; - public static final String KEY_USER_CACHE_DIR = "deployment.user.cachedir"; public static final String KEY_USER_PERSISTENCE_CACHE_DIR = "deployment.user.pcachedir"; public static final String KEY_SYSTEM_CACHE_DIR = "deployment.system.cachedir"; @@ -172,6 +165,24 @@ public static final String KEY_SECURITY_INSTALL_AUTHENTICATOR = "deployment.security.authenticator"; /* + * Networking + */ + public static final String KEY_PROXY_TYPE = "deployment.proxy.type"; + public static final String KEY_PROXY_SAME = "deployment.proxy.same"; + public static final String KEY_PROXY_AUTO_CONFIG_URL = "deployment.proxy.auto.config.url"; + public static final String KEY_PROXY_BYPASS_LIST = "deployment.proxy.bypass.list"; + public static final String KEY_PROXY_BYPASS_LOCAL = "deployment.proxy.bypass.local"; + public static final String KEY_PROXY_HTTP_HOST = "deployment.proxy.http.host"; + public static final String KEY_PROXY_HTTP_PORT = "deployment.proxy.http.port"; + public static final String KEY_PROXY_HTTPS_HOST = "deployment.proxy.https.host"; + public static final String KEY_PROXY_HTTPS_PORT = "deployment.proxy.https.port"; + public static final String KEY_PROXY_FTP_HOST = "deployment.proxy.ftp.host"; + public static final String KEY_PROXY_FTP_PORT = "deployment.proxy.ftp.port"; + public static final String KEY_PROXY_SOCKS4_HOST = "deployment.proxy.socks.host"; + public static final String KEY_PROXY_SOCKS4_PORT = "deployment.proxy.socks.port"; + public static final String KEY_PROXY_OVERRIDE_HOSTS = "deployment.proxy.override.hosts"; + + /* * Tracing and Logging */ @@ -380,20 +391,20 @@ { KEY_SECURITY_PROMPT_USER_FOR_JNLP, String.valueOf(true) }, { KEY_SECURITY_INSTALL_AUTHENTICATOR, String.valueOf(true) }, /* networking */ - { "deployment.proxy.type", String.valueOf(PROXY_TYPE_BROWSER) }, - { "deployment.proxy.same", String.valueOf(false) }, - { "deployment.proxy.auto.config.url", null }, - { "deployment.proxy.bypass.list", null }, - { "deployment.proxy.bypass.local", null }, - { "deployment.proxy.http.host", null }, - { "deployment.proxy.http.port", null }, - { "deployment.proxy.https.host", null }, - { "deployment.proxy.https.port", null }, - { "deployment.proxy.ftp.host", null }, - { "deployment.proxy.ftp.port", null }, - { "deployment.proxy.socks.host", null }, - { "deployment.proxy.socks.port", null }, - { "deployment.proxy.override.hosts", null }, + { KEY_PROXY_TYPE, String.valueOf(JNLPProxySelector.PROXY_TYPE_BROWSER) }, + { KEY_PROXY_SAME, String.valueOf(false) }, + { KEY_PROXY_AUTO_CONFIG_URL, null }, + { KEY_PROXY_BYPASS_LIST, null }, + { KEY_PROXY_BYPASS_LOCAL, null }, + { KEY_PROXY_HTTP_HOST, null }, + { KEY_PROXY_HTTP_PORT, null }, + { KEY_PROXY_HTTPS_HOST, null }, + { KEY_PROXY_HTTPS_PORT, null }, + { KEY_PROXY_FTP_HOST, null }, + { KEY_PROXY_FTP_PORT, null }, + { KEY_PROXY_SOCKS4_HOST, null }, + { KEY_PROXY_SOCKS4_PORT, null }, + { KEY_PROXY_OVERRIDE_HOSTS, null }, /* cache and optional package repository */ { "deployment.cache.max.size", String.valueOf("-1") }, { "deployment.cache.jarcompression", String.valueOf(0) },
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netx/net/sourceforge/jnlp/runtime/JNLPProxySelector.java Tue Nov 23 10:05:06 2010 -0500 @@ -0,0 +1,360 @@ +// Copyright (C) 2010 Red Hat, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +package net.sourceforge.jnlp.runtime; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.net.URL; +import java.net.UnknownHostException; +import java.net.Proxy.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; + +/** + * A ProxySelector specific to JNLPs. This proxy uses the deployment + * configuration to determine what to do. + * + * @see java.net.ProxySelector + */ +public class JNLPProxySelector extends ProxySelector { + + public static final int PROXY_TYPE_UNKNOWN = -1; + public static final int PROXY_TYPE_NONE = 0; + public static final int PROXY_TYPE_MANUAL = 1; + public static final int PROXY_TYPE_AUTO = 2; + public static final int PROXY_TYPE_BROWSER = 3; + + /** The default port to use as a fallback. Currently squid's default port */ + public static final int FALLBACK_PROXY_PORT = 3128; + + /** The proxy type. See PROXY_TYPE_* constants */ + private int proxyType = PROXY_TYPE_UNKNOWN; + + /** the URL to the PAC file */ + private URL autoConfigUrl = null; + + /** a list of URLs that should be bypassed for proxy purposes */ + private List<String> bypassList = null; + + /** whether localhost should be bypassed for proxy purposes */ + private boolean bypassLocal = false; + + /** + * whether the http proxy should be used for https and ftp protocols as well + */ + private boolean sameProxy = false; + + private String proxyHttpHost; + private int proxyHttpPort; + private String proxyHttpsHost; + private int proxyHttpsPort; + private String proxyFtpHost; + private int proxyFtpPort; + private String proxySocks4Host; + private int proxySocks4Port; + + // FIXME what is this? where should it be used? + private String overrideHosts = null; + + /** + * Creates a new JNLPProxySelector. + */ + public JNLPProxySelector() { + parseConfiguration(); + } + + /** + * Initialize this ProxySelector by reading the configuration + */ + private void parseConfiguration() { + DeploymentConfiguration config = JNLPRuntime.getConfiguration(); + + proxyType = Integer.valueOf(config.getProperty(DeploymentConfiguration.KEY_PROXY_TYPE)); + + String autoConfigString = config + .getProperty(DeploymentConfiguration.KEY_PROXY_AUTO_CONFIG_URL); + if (autoConfigString != null) { + try { + autoConfigUrl = new URL(autoConfigString); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + bypassList = new ArrayList<String>(); + String proxyBypass = config.getProperty(DeploymentConfiguration.KEY_PROXY_BYPASS_LIST); + if (proxyBypass != null) { + StringTokenizer tokenizer = new StringTokenizer(proxyBypass, ","); + while (tokenizer.hasMoreTokens()) { + String host = tokenizer.nextToken(); + if (host != null && host.trim().length() != 0) { + bypassList.add(host); + } + } + } + + bypassLocal = Boolean.valueOf(config + .getProperty(DeploymentConfiguration.KEY_PROXY_BYPASS_LOCAL)); + + sameProxy = Boolean.valueOf(config.getProperty(DeploymentConfiguration.KEY_PROXY_SAME)); + + proxyHttpHost = getHost(config, DeploymentConfiguration.KEY_PROXY_HTTP_HOST); + proxyHttpPort = getPort(config, DeploymentConfiguration.KEY_PROXY_HTTP_PORT); + + proxyHttpsHost = getHost(config, DeploymentConfiguration.KEY_PROXY_HTTPS_HOST); + proxyHttpsPort = getPort(config, DeploymentConfiguration.KEY_PROXY_HTTPS_PORT); + + proxyFtpHost = getHost(config, DeploymentConfiguration.KEY_PROXY_FTP_HOST); + proxyFtpPort = getPort(config, DeploymentConfiguration.KEY_PROXY_FTP_PORT); + + proxySocks4Host = getHost(config, DeploymentConfiguration.KEY_PROXY_SOCKS4_HOST); + proxySocks4Port = getPort(config, DeploymentConfiguration.KEY_PROXY_SOCKS4_PORT); + + overrideHosts = config.getProperty(DeploymentConfiguration.KEY_PROXY_OVERRIDE_HOSTS); + } + + /** + * Uses the given key to get a host from the configuraion + */ + private String getHost(DeploymentConfiguration config, String key) { + String proxyHost = config.getProperty(key); + if (proxyHost != null) { + proxyHost = proxyHost.trim(); + } + return proxyHost; + } + + /** + * Uses the given key to get a port from the configuration + */ + private int getPort(DeploymentConfiguration config, String key) { + int proxyPort = FALLBACK_PROXY_PORT; + String port; + port = config.getProperty(key); + if (port != null && port.trim().length() != 0) { + try { + proxyPort = Integer.valueOf(port); + } catch (NumberFormatException e) { + e.printStackTrace(); + } + } + return proxyPort; + } + + /** + * {@inheritDoc} + */ + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + ioe.printStackTrace(); + } + + /** + * {@inheritDoc} + */ + @Override + public List<Proxy> select(URI uri) { + if (JNLPRuntime.isDebug()) { + System.out.println("Selecting proxy for: " + uri); + } + + if (inBypassList(uri)) { + List<Proxy> proxies = Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); + if (JNLPRuntime.isDebug()) { + System.out.println("Selected proxies: " + Arrays.toString(proxies.toArray())); + } + return proxies; + } + + List<Proxy> proxies = new ArrayList<Proxy>(); + + switch (proxyType) { + case PROXY_TYPE_MANUAL: + proxies.addAll(getFromConfiguration(uri)); + break; + case PROXY_TYPE_AUTO: + proxies.addAll(getFromPAC(uri)); + break; + case PROXY_TYPE_BROWSER: + proxies.addAll(getFromBrowser(uri)); + break; + case PROXY_TYPE_UNKNOWN: + // fall through + case PROXY_TYPE_NONE: + // fall through + default: + proxies.add(Proxy.NO_PROXY); + break; + } + + if (JNLPRuntime.isDebug()) { + System.out.println("Selected proxies: " + Arrays.toString(proxies.toArray())); + } + return proxies; + } + + /** + * Returns true if the uri should be bypassed for proxy purposes + */ + private boolean inBypassList(URI uri) { + try { + String scheme = uri.getScheme(); + /* scheme can be http/https/ftp/socket */ + + if (scheme.equals("http") || scheme.equals("https") || scheme.equals("ftp")) { + URL url = uri.toURL(); + if (bypassLocal && isLocalHost(url.getHost())) { + return true; + } + + if (bypassList.contains(url.getHost())) { + return true; + } + } else if (scheme.equals("socket")) { + String host = uri.getSchemeSpecificPart().split(":")[0]; + + if (bypassLocal && isLocalHost(host)) { + return true; + } + + if (bypassList.contains(host)) { + return true; + } + } + } catch (MalformedURLException e) { + return false; + } + + return false; + } + + /** + * Returns true if the host is the hostname or the IP address of the + * localhost + */ + private boolean isLocalHost(String host) { + + try { + if (InetAddress.getByName(host).isLoopbackAddress()) { + return true; + } + } catch (UnknownHostException e1) { + // continue + } + + try { + if (host.equals(InetAddress.getLocalHost().getHostName())) { + return true; + } + } catch (UnknownHostException e) { + // continue + } + + try { + if (host.equals(InetAddress.getLocalHost().getHostAddress())) { + return true; + } + } catch (UnknownHostException e) { + // continue + } + + return false; + } + + /** + * Returns a list of proxies by using the information in the deployment + * configuration + * + * @param uri + * @return a List of Proxy objects + */ + private List<Proxy> getFromConfiguration(URI uri) { + List<Proxy> proxies = new ArrayList<Proxy>(); + + String scheme = uri.getScheme(); + + if (sameProxy) { + SocketAddress sa = new InetSocketAddress(proxyHttpHost, proxyHttpPort); + Proxy proxy; + if (scheme.equals("socket")) { + proxy = new Proxy(Type.SOCKS, sa); + } else { + proxy = new Proxy(Type.HTTP, sa); + } + proxies.add(proxy); + } else if (scheme.equals("http")) { + SocketAddress sa = new InetSocketAddress(proxyHttpHost, proxyHttpPort); + proxies.add(new Proxy(Type.HTTP, sa)); + } else if (scheme.equals("https")) { + SocketAddress sa = new InetSocketAddress(proxyHttpsHost, proxyHttpsPort); + proxies.add(new Proxy(Type.HTTP, sa)); + } else if (scheme.equals("ftp")) { + SocketAddress sa = new InetSocketAddress(proxyFtpHost, proxyFtpPort); + proxies.add(new Proxy(Type.HTTP, sa)); + } else if (scheme.equals("socket")) { + SocketAddress sa = new InetSocketAddress(proxySocks4Host, proxySocks4Port); + proxies.add(new Proxy(Type.SOCKS, sa)); + } else { + proxies.add(Proxy.NO_PROXY); + } + + return proxies; + } + + /** + * Returns a list of proxies by using the Proxy Auto Config (PAC) file. See + * http://en.wikipedia.org/wiki/Proxy_auto-config#The_PAC_file for more + * information. + * + * @return a List of valid Proxy objects + */ + private List<Proxy> getFromPAC(URI uri) { + if (autoConfigUrl == null) { + return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); + } + // TODO implement this by reading and using the PAC file + if (JNLPRuntime.isDebug()) { + System.err.println("WARNING: Using a Proxy Auto Config file is not implemented yet"); + } + + return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); + } + + /** + * Returns a list of proxies by querying the browser + * + * @param uri the uri to get proxies for + * @return a list of proxies + */ + protected List<Proxy> getFromBrowser(URI uri) { + // TODO implement this by parsing mozilla config + if (JNLPRuntime.isDebug()) { + System.err.println("WARNING: Using proxy settings from the browser is not implemented yet"); + } + + return Arrays.asList(new Proxy[] { Proxy.NO_PROXY }); + } + +}
--- a/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Fri Nov 19 10:35:27 2010 -0500 +++ b/netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java Tue Nov 23 10:05:06 2010 -0500 @@ -18,6 +18,8 @@ package net.sourceforge.jnlp.runtime; import java.io.*; +import java.net.Authenticator; +import java.net.ProxySelector; import java.nio.channels.FileLock; import java.awt.*; import java.text.*; @@ -35,6 +37,7 @@ import net.sourceforge.jnlp.*; import net.sourceforge.jnlp.cache.*; +import net.sourceforge.jnlp.security.JNLPAuthenticator; import net.sourceforge.jnlp.security.SecurityDialogMessageHandler; import net.sourceforge.jnlp.security.VariableX509TrustManager; import net.sourceforge.jnlp.services.*; @@ -250,6 +253,10 @@ e.printStackTrace(); } + // plug in a custom authenticator and proxy selector + Authenticator.setDefault(new JNLPAuthenticator()); + ProxySelector.setDefault(new JNLPProxySelector()); + initialized = true; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netx/net/sourceforge/jnlp/security/JNLPAuthenticator.java Tue Nov 23 10:05:06 2010 -0500 @@ -0,0 +1,61 @@ +/* JNLPAuthenticator + Copyright (C) 2008 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package net.sourceforge.jnlp.security; + +import java.net.Authenticator; +import java.net.PasswordAuthentication; + +public class JNLPAuthenticator extends Authenticator { + + public PasswordAuthentication getPasswordAuthentication() { + + // No security check is required here, because the only way to set + // parameters for which auth info is needed + // (Authenticator:requestPasswordAuthentication()), has a security check + + String type = this.getRequestorType() == RequestorType.PROXY ? "proxy" : "web"; + + // request auth info from user + PasswordAuthenticationDialog pwDialog = new PasswordAuthenticationDialog(); + PasswordAuthentication auth = pwDialog.askUser(this.getRequestingHost(), this.getRequestingPort(), this.getRequestingPrompt(), type); + + // send it along + return auth; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/netx/net/sourceforge/jnlp/security/PasswordAuthenticationDialog.java Tue Nov 23 10:05:06 2010 -0500 @@ -0,0 +1,247 @@ +/* PasswordAuthenticationDialog -- requests authentication information from users + Copyright (C) 2009 Red Hat + +This file is part of IcedTea. + +IcedTea is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +IcedTea is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with IcedTea; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package net.sourceforge.jnlp.security; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.net.PasswordAuthentication; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; + +import net.sourceforge.jnlp.runtime.JNLPRuntime; + +/** + * Modal non-minimizable dialog to request http authentication credentials + */ + +public class PasswordAuthenticationDialog extends JDialog { + + private JLabel jlInfo = new JLabel(""); + private JTextField jtfUserName = new JTextField(); + private JPasswordField jpfPassword = new JPasswordField(); + private boolean userCancelled; + + public PasswordAuthenticationDialog() { + initialize(); + } + + /** + * Initialized the dialog components + */ + + public void initialize() { + + setTitle("IcedTea Java Plugin - Authorization needed to proceed"); + + setLayout(new GridBagLayout()); + + JLabel jlUserName = new JLabel("Username: "); + JLabel jlPassword = new JLabel("Password: "); + JButton jbOK = new JButton("OK"); + JButton jbCancel = new JButton("Cancel"); + + jtfUserName.setSize(20, 10); + jpfPassword.setSize(20, 10); + + GridBagConstraints c; + + c = new GridBagConstraints(); + c.fill = c.HORIZONTAL; + c.gridx = 0; + c.gridy = 0; + c.gridwidth = 2; + c.insets = new Insets(10, 5, 3, 3); + add(jlInfo, c); + + c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 1; + c.insets = new Insets(10, 5, 3, 3); + add(jlUserName, c); + + c = new GridBagConstraints(); + c.fill = c.HORIZONTAL; + c.gridx = 1; + c.gridy = 1; + c.insets = new Insets(10, 5, 3, 3); + c.weightx = 1.0; + add(jtfUserName, c); + + + c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 2; + c.insets = new Insets(5, 5, 3, 3); + add(jlPassword, c); + + c = new GridBagConstraints(); + c.fill = c.HORIZONTAL; + c.gridx = 1; + c.gridy = 2; + c.insets = new Insets(5, 5, 3, 3); + c.weightx = 1.0; + add(jpfPassword, c); + + c = new GridBagConstraints(); + c.anchor = c.SOUTHEAST; + c.gridx = 1; + c.gridy = 3; + c.insets = new Insets(5, 5, 3, 70); + c.weightx = 0.0; + add(jbCancel, c); + + c = new GridBagConstraints(); + c.anchor = c.SOUTHEAST; + c.gridx = 1; + c.gridy = 3; + c.insets = new Insets(5, 5, 3, 3); + c.weightx = 0.0; + add(jbOK, c); + + setMinimumSize(new Dimension(400,150)); + setMaximumSize(new Dimension(1024,150)); + setAlwaysOnTop(true); + + setSize(400,150); + setLocationRelativeTo(null); + + // OK => read supplied info and pass it on + jbOK.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + userCancelled = false; + dispose(); + } + }); + + // Cancel => discard supplied info and pass on an empty auth + jbCancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + userCancelled = true; + dispose(); + } + }); + + // "return" key in either user or password field => OK + + jtfUserName.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + userCancelled = false; + dispose(); + } + }); + + jpfPassword.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + userCancelled = false; + dispose(); + } + }); + } + + /** + * Present a dialog to the user asking them for authentication information + * + * @param hostThe host for with authentication is needed + * @param port The port being accessed + * @param prompt The prompt (realm) as presented by the server + * @param type The type of server (proxy/web) + * @return PasswordAuthentication containing the credentials (empty credentials if user cancelled) + */ + protected PasswordAuthentication askUser(String host, int port, String prompt, String type) { + PasswordAuthentication auth = null; + + host += port != -1 ? ":" + port : ""; + + // This frame is reusable. So reset everything first. + userCancelled = true; + jlInfo.setText("<html>The " + type + " server at " + host + " is requesting authentication. It says \"" + prompt + "\"</html>"); + + try { + SwingUtilities.invokeAndWait( new Runnable() { + public void run() { + // show dialog to user + setVisible(true); + } + }); + + if (JNLPRuntime.isDebug()) { + System.out.println("password dialog shown"); + } + + // wait until dialog is gone + while (this.isShowing()) { + try { + Thread.sleep(200); + } catch (InterruptedException ie) { + } + } + + if (JNLPRuntime.isDebug()) { + System.out.println("password dialog closed"); + } + + if (!userCancelled) { + auth = new PasswordAuthentication(jtfUserName.getText(), jpfPassword.getText().toCharArray()); + } + } catch (Exception e) { + e.printStackTrace(); + + // Nothing else we can do. Empty auth will be returned + } + + return auth; + } + + public static void main(String[] args) { + PasswordAuthenticationDialog frame = new PasswordAuthenticationDialog(); + + PasswordAuthentication auth = frame.askUser("127.0.0.1", 3128, "Password for local proxy", "proxy"); + + System.err.println("Auth info: " + auth.getUserName() + ":" + new String(auth.getPassword())); + System.exit(0); + } +}
--- a/plugin/icedteanp/java/sun/applet/PasswordAuthenticationDialog.java Fri Nov 19 10:35:27 2010 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -/* PasswordAuthenticationDialog -- requests authentication information from users - Copyright (C) 2009 Red Hat - -This file is part of IcedTea. - -IcedTea is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -IcedTea is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with IcedTea; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - -package sun.applet; - -import java.awt.Dimension; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.net.PasswordAuthentication; - -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JPasswordField; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; - -/** - * Modal non-minimizable dialog to request http authentication credentials - */ - -public class PasswordAuthenticationDialog extends JDialog { - - private JLabel jlInfo = new JLabel(""); - private JTextField jtfUserName = new JTextField(); - private JPasswordField jpfPassword = new JPasswordField(); - private boolean userCancelled; - - public PasswordAuthenticationDialog() { - initialize(); - } - - /** - * Initialized the dialog components - */ - - public void initialize() { - - setTitle("IcedTea Java Plugin - Authorization needed to proceed"); - - setLayout(new GridBagLayout()); - - JLabel jlUserName = new JLabel("Username: "); - JLabel jlPassword = new JLabel("Password: "); - JButton jbOK = new JButton("OK"); - JButton jbCancel = new JButton("Cancel"); - - jtfUserName.setSize(20, 10); - jpfPassword.setSize(20, 10); - - GridBagConstraints c; - - c = new GridBagConstraints(); - c.fill = c.HORIZONTAL; - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 2; - c.insets = new Insets(10, 5, 3, 3); - add(jlInfo, c); - - c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 1; - c.insets = new Insets(10, 5, 3, 3); - add(jlUserName, c); - - c = new GridBagConstraints(); - c.fill = c.HORIZONTAL; - c.gridx = 1; - c.gridy = 1; - c.insets = new Insets(10, 5, 3, 3); - c.weightx = 1.0; - add(jtfUserName, c); - - - c = new GridBagConstraints(); - c.gridx = 0; - c.gridy = 2; - c.insets = new Insets(5, 5, 3, 3); - add(jlPassword, c); - - c = new GridBagConstraints(); - c.fill = c.HORIZONTAL; - c.gridx = 1; - c.gridy = 2; - c.insets = new Insets(5, 5, 3, 3); - c.weightx = 1.0; - add(jpfPassword, c); - - c = new GridBagConstraints(); - c.anchor = c.SOUTHEAST; - c.gridx = 1; - c.gridy = 3; - c.insets = new Insets(5, 5, 3, 70); - c.weightx = 0.0; - add(jbCancel, c); - - c = new GridBagConstraints(); - c.anchor = c.SOUTHEAST; - c.gridx = 1; - c.gridy = 3; - c.insets = new Insets(5, 5, 3, 3); - c.weightx = 0.0; - add(jbOK, c); - - setMinimumSize(new Dimension(400,150)); - setMaximumSize(new Dimension(1024,150)); - setAlwaysOnTop(true); - - setSize(400,150); - setLocationRelativeTo(null); - - // OK => read supplied info and pass it on - jbOK.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - userCancelled = false; - dispose(); - } - }); - - // Cancel => discard supplied info and pass on an empty auth - jbCancel.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - userCancelled = true; - dispose(); - } - }); - - // "return" key in either user or password field => OK - - jtfUserName.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - userCancelled = false; - dispose(); - } - }); - - jpfPassword.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - userCancelled = false; - dispose(); - } - }); - } - - /** - * Present a dialog to the user asking them for authentication information - * - * @param hostThe host for with authentication is needed - * @param port The port being accessed - * @param prompt The prompt (realm) as presented by the server - * @param type The type of server (proxy/web) - * @return PasswordAuthentication containing the credentials (empty credentials if user cancelled) - */ - protected PasswordAuthentication askUser(String host, int port, String prompt, String type) { - PasswordAuthentication auth = null; - - host += port != -1 ? ":" + port : ""; - - // This frame is reusable. So reset everything first. - userCancelled = true; - jlInfo.setText("<html>The " + type + " server at " + host + " is requesting authentication. It says \"" + prompt + "\"</html>"); - - try { - SwingUtilities.invokeAndWait( new Runnable() { - public void run() { - // show dialog to user - setVisible(true); - } - }); - - PluginDebug.debug("password dialog shown"); - - // wait until dialog is gone - while (this.isShowing()) { - try { - Thread.sleep(200); - } catch (InterruptedException ie) { - } - } - - PluginDebug.debug("password dialog closed"); - - if (!userCancelled) { - auth = new PasswordAuthentication(jtfUserName.getText(), jpfPassword.getText().toCharArray()); - } - } catch (Exception e) { - e.printStackTrace(); - - // Nothing else we can do. Empty auth will be returned - } - - return auth; - } - - public static void main(String[] args) { - PasswordAuthenticationDialog frame = new PasswordAuthenticationDialog(); - - PasswordAuthentication auth = frame.askUser("127.0.0.1", 3128, "Password for local proxy", "proxy"); - - System.err.println("Auth info: " + auth.getUserName() + ":" + new String(auth.getPassword())); - System.exit(0); - } -}
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java Fri Nov 19 10:35:27 2010 -0500 +++ b/plugin/icedteanp/java/sun/applet/PluginMain.java Tue Nov 23 10:05:06 2010 -0500 @@ -77,6 +77,7 @@ import net.sourceforge.jnlp.runtime.DeploymentConfiguration; import net.sourceforge.jnlp.runtime.JNLPRuntime; +import net.sourceforge.jnlp.security.JNLPAuthenticator; /** * The main entry point into PluginAppletViewer. @@ -202,8 +203,9 @@ boolean installAuthenticator = Boolean.valueOf(JNLPRuntime.getConfiguration() .getProperty(DeploymentConfiguration.KEY_SECURITY_INSTALL_AUTHENTICATOR)); if (installAuthenticator) { - Authenticator.setDefault(new CustomAuthenticator()); + Authenticator.setDefault(new JNLPAuthenticator()); } + // override the proxy selector set by JNLPRuntime ProxySelector.setDefault(new PluginProxySelector()); CookieManager ckManager = new PluginCookieManager(); @@ -218,24 +220,4 @@ return streamHandler.getMessage(); } - static class CustomAuthenticator extends Authenticator { - - public PasswordAuthentication getPasswordAuthentication() { - - // No security check is required here, because the only way to - // set parameters for which auth info is needed - // (Authenticator:requestPasswordAuthentication()), has a security - // check - - String type = this.getRequestorType() == RequestorType.PROXY ? "proxy" : "web"; - - // request auth info from user - PasswordAuthenticationDialog pwDialog = new PasswordAuthenticationDialog(); - PasswordAuthentication auth = pwDialog.askUser(this.getRequestingHost(), this.getRequestingPort(), this.getRequestingPrompt(), type); - - // send it along - return auth; - } - } - }
--- a/plugin/icedteanp/java/sun/applet/PluginProxySelector.java Fri Nov 19 10:35:27 2010 -0500 +++ b/plugin/icedteanp/java/sun/applet/PluginProxySelector.java Tue Nov 23 10:05:06 2010 -0500 @@ -37,18 +37,16 @@ package sun.applet; -import java.io.IOException; -import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Proxy; -import java.net.ProxySelector; -import java.net.SocketAddress; import java.net.URI; import java.util.Date; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import net.sourceforge.jnlp.runtime.JNLPProxySelector; + /** * Proxy selector implementation for plugin network functions. * @@ -58,17 +56,10 @@ * */ -public class PluginProxySelector extends ProxySelector { +public class PluginProxySelector extends JNLPProxySelector { private TimedHashMap<String, Proxy> proxyCache = new TimedHashMap<String, Proxy>(); - - @Override - public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { - // If the connection fails, there is little we can do here. Just print the exception - ioe.printStackTrace(); - } - /** * Selects the appropriate proxy (or DIRECT connection method) for the given URI * @@ -76,7 +67,7 @@ * @return A list of Proxy objects that are usable for this URI */ @Override - public List<Proxy> select(URI uri) { + protected List<Proxy> getFromBrowser(URI uri) { List<Proxy> proxyList = new ArrayList<Proxy>();