| /******************************************************************************* |
| * Copyright (c) 2010 The Eclipse Foundation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * The Eclipse Foundation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.epp.internal.mpc.core.util; |
| |
| import java.net.Authenticator; |
| import java.net.InetAddress; |
| import java.net.PasswordAuthentication; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.net.UnknownHostException; |
| import java.text.MessageFormat; |
| |
| import org.eclipse.core.net.proxy.IProxyData; |
| import org.eclipse.core.net.proxy.IProxyService; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.RegistryFactory; |
| import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore; |
| import org.eclipse.osgi.util.NLS; |
| |
| class ProxyAuthenticator extends Authenticator { |
| private static final String EGIT_AUTHENTICATOR_CLASS = "org.eclipse.egit.core.EclipseAuthenticator"; //$NON-NLS-1$ |
| |
| private final Authenticator delegate; |
| |
| private final Authenticator previousAuthenticator; |
| |
| public ProxyAuthenticator(Authenticator delegate) { |
| if (delegate instanceof ProxyAuthenticator) { |
| delegate = ((ProxyAuthenticator) delegate).getDelegate(); |
| } |
| this.previousAuthenticator = delegate; |
| this.delegate = fixDelegate(delegate); |
| } |
| |
| private static Authenticator fixDelegate(Authenticator delegate) { |
| if (delegate == null) { |
| return null; |
| } |
| if (EGIT_AUTHENTICATOR_CLASS.equals(delegate.getClass().getName())) { |
| Authenticator replacement = getPluggedInNonEGitAuthenticator(); |
| if (replacement != null) { |
| return replacement; |
| } |
| } |
| return delegate; |
| } |
| |
| private static Authenticator getPluggedInNonEGitAuthenticator() { |
| @SuppressWarnings("restriction") |
| IExtension[] extensions = RegistryFactory.getRegistry() |
| .getExtensionPoint(org.eclipse.core.internal.net.Activator.ID, |
| org.eclipse.core.internal.net.Activator.PT_AUTHENTICATOR) |
| .getExtensions(); |
| if (extensions.length == 0) { |
| return null; |
| } |
| IConfigurationElement config = null; |
| for (IExtension extension : extensions) { |
| IConfigurationElement[] configs = extension.getConfigurationElements(); |
| if (configs.length == 0) { |
| continue; |
| } |
| String className = configs[0].getAttribute("class"); //$NON-NLS-1$ |
| if (className != null && !EGIT_AUTHENTICATOR_CLASS.equals(className)) { |
| config = configs[0]; |
| break; |
| } |
| } |
| if (config != null) { |
| try { |
| return (Authenticator) config.createExecutableExtension("class");//$NON-NLS-1$ |
| } catch (CoreException ex) { |
| MarketplaceClientCore.error(NLS.bind("Unable to instantiate authenticator {0}", //$NON-NLS-1$ |
| (new Object[] { config.getDeclaringExtension().getUniqueIdentifier() })), ex); |
| } |
| } |
| return null; |
| } |
| |
| private boolean hostMatches(final IProxyData proxy) { |
| String proxyHost = proxy.getHost(); |
| if (proxyHost == null) { |
| return false; |
| } |
| try { |
| InetAddress requestingAddress = getRequestingSite(); |
| if (requestingAddress != null) { |
| final InetAddress proxyAddress = InetAddress.getByName(proxyHost); |
| return proxyAddress.equals(requestingAddress); |
| } |
| } catch (UnknownHostException err) { |
| return false; |
| } |
| String requestingHost = getRequestingHost(); |
| if (requestingHost != null && requestingHost.equals(proxyHost)) { |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| protected PasswordAuthentication getPasswordAuthentication() { |
| IProxyService proxyService = ProxyHelper.getProxyService(); |
| if (proxyService != null && proxyService.isProxiesEnabled()) { |
| URL requestingURL = getRequestingURL(); |
| IProxyData[] proxies; |
| if (requestingURL == null) { |
| proxies = proxyService.getProxyData(); |
| } else { |
| try { |
| proxies = proxyService.select(requestingURL.toURI()); |
| } catch (URISyntaxException e) { |
| proxies = proxyService.getProxyData(); |
| } |
| } |
| |
| for (IProxyData proxyData : proxies) { |
| // make sure we don't hand out credentials to the wrong proxy |
| if (proxyData.isRequiresAuthentication() && proxyData.getPort() == getRequestingPort() |
| && hostMatches(proxyData)) { |
| String userId = proxyData.getUserId(); |
| String password = proxyData.getPassword(); |
| if (userId != null && password != null) { |
| return new PasswordAuthentication(userId, password.toCharArray()); |
| } |
| } |
| } |
| } |
| if (delegate != null) { |
| // Pass on to previously registered authenticator |
| // Eclipse UI bundle registers one to query credentials from user |
| try { |
| Authenticator.setDefault(delegate); |
| String requestingHost = getRequestingHost(); |
| InetAddress requestingSite = getRequestingSite(); |
| int requestingPort = getRequestingPort(); |
| String requestingProtocol = getRequestingProtocol(); |
| String requestingPrompt = getRequestingPrompt(); |
| String requestingScheme = getRequestingScheme(); |
| URL requestingURL = getRequestingURL(); |
| RequestorType requestorType = getRequestorType(); |
| if (requestingSite == null) { |
| try { |
| requestingSite = InetAddress.getByName(requestingHost); |
| } catch (Exception ex) { |
| //ignore |
| } |
| } |
| if (requestingPrompt == null) { |
| //Help the Eclipse UI password dialog with its prompt |
| String promptHost = requestingSite == null ? String.format("%s:%s", requestingHost, requestingPort) //$NON-NLS-1$ |
| : requestingHost == null ? requestingSite.getHostName() : requestingHost; |
| String promptType = requestorType.toString().toLowerCase(); |
| requestingPrompt = MessageFormat.format(Messages.ProxyAuthenticator_prompt, requestingScheme, |
| promptType, promptHost); |
| } |
| return Authenticator.requestPasswordAuthentication(requestingHost, requestingSite, requestingPort, |
| requestingProtocol, requestingPrompt, requestingScheme, requestingURL, requestorType); |
| } finally { |
| Authenticator.setDefault(this); |
| } |
| } |
| return null; |
| } |
| |
| public Authenticator getDelegate() { |
| return delegate; |
| } |
| |
| public void install() { |
| Authenticator.setDefault(this); |
| } |
| |
| public void uninstall() { |
| synchronized (Authenticator.class) { |
| Authenticator defaultAuthenticator = ProxyHelper.getDefaultAuthenticator(); |
| if (defaultAuthenticator == this) { |
| Authenticator.setDefault(previousAuthenticator); |
| } |
| } |
| } |
| } |