| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.update.internal.ui.security; |
| |
| |
| import java.net.*; |
| import java.util.*; |
| |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.update.core.*; |
| import org.eclipse.update.internal.ui.*; |
| |
| /** |
| * A transient database that remembers information, such as usernames and |
| * passwords. The information is stored in memory only and is discarted |
| * when the Plaform shuts down. |
| */ |
| public class UpdateManagerAuthenticator extends Authenticator { |
| |
| // fields needed for caching the password |
| public static final String INFO_PASSWORD = "password"; //$NON-NLS-1$ |
| public static final String INFO_USERNAME = "username"; //$NON-NLS-1$ |
| public static final String UNKNOWN_HOST = "unknown"; //$NON-NLS-1$ |
| public static final String AUTH_SCHEME = ""; //$NON-NLS-1$ |
| |
| private String requestingHostName; |
| private int requestingPort; |
| private String requestingProtocol; |
| private String requestingPrompt; |
| private String requestingScheme; |
| private Map savedPasswordAuthentication; |
| |
| /** |
| * The Map containing the userid and password |
| * HashMap allows <code>null</code> as the value |
| */ |
| private Map result = new HashMap(); |
| |
| /** |
| * |
| */ |
| public void addAuthenticationInfo(URL serverUrl, String realm, String scheme, Map info) { |
| try { |
| Platform.addAuthorizationInfo(serverUrl, realm, scheme, info); |
| } catch (CoreException e) { |
| UpdateUI.logException(e); |
| } |
| } |
| |
| /** |
| * |
| */ |
| public Map getAuthenticationInfo(URL serverUrl, String realm, String scheme) { |
| return Platform.getAuthorizationInfo(serverUrl, realm, scheme); |
| } |
| |
| /** |
| * |
| */ |
| public Map requestAuthenticationInfo(URL resourceUrl, String realm, String scheme) { |
| // already called by retrieve |
| //if (!equalsPreviousRequest(resourceUrl, realm, scheme)) { |
| // save state |
| this.requestingPort = resourceUrl.getPort(); |
| this.requestingPrompt = realm; |
| this.requestingProtocol = resourceUrl.getProtocol(); |
| this.requestingScheme = scheme; |
| this.requestingHostName = resourceUrl.getHost(); |
| |
| // try to get the password info from the in-memory database first |
| Map map = Platform.getAuthorizationInfo(resourceUrl, requestingPrompt, requestingScheme); |
| if (map == null) { |
| map = retrievePasswordAuthentication(resourceUrl, requestingPrompt, requestingScheme); |
| } |
| savedPasswordAuthentication = map; |
| //} |
| |
| // we must return a valid Map while we internally manage Cancel dialog (map==null -> dialog cancelled) |
| return savedPasswordAuthentication; |
| } |
| |
| /** |
| * @see org.eclipse.update.internal.core.net.http.client.IAuthenticator#addProtectionSpace(URL, String) |
| */ |
| public void addProtectionSpace(URL resourceUrl, String realm) { |
| try { |
| Platform.addProtectionSpace(resourceUrl, realm); |
| } catch (CoreException e) { |
| UpdateUI.logException(e, false); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.update.internal.core.net.http.client.IAuthenticator#getProtectionSpace(URL) |
| */ |
| public String getProtectionSpace(URL resourceUrl) { |
| return Platform.getProtectionSpace(resourceUrl); |
| } |
| |
| /* |
| * forces a refresh |
| */ |
| public void reset() { |
| requestingPort = 0; |
| requestingPrompt = null; |
| requestingProtocol = null; |
| requestingScheme = null; |
| requestingHostName = null; |
| } |
| |
| /* |
| * returns a map that contains the userid and the password |
| * or <code>null</code> if the dialog has been cancelled |
| */ |
| private Map retrievePasswordAuthentication(final URL resourceUrl, final String realm, final String scheme) { |
| result = new HashMap(); |
| if ("Basic".equalsIgnoreCase(scheme) || "NTLM".equalsIgnoreCase(scheme)) { //$NON-NLS-1$ |
| Display disp = Display.getCurrent(); |
| if (disp != null) { |
| result = promptForPassword(resourceUrl, realm); |
| } else { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| result = promptForPassword(resourceUrl, realm); |
| } |
| }); |
| } |
| } |
| return result; |
| } |
| |
| /* |
| * returns true if this request is the same as the saved one |
| * used to prevent double dialog if user cancelled or entered wrong userid/password |
| */ |
| private boolean equalsPreviousRequest(URL url, String realm, String scheme) { |
| |
| if (requestingPort != url.getPort()) |
| return false; |
| |
| if (requestingPrompt != null && !requestingPrompt.equals(realm)) |
| return false; |
| if (requestingPrompt == null && realm != null) |
| return false; |
| |
| if (requestingProtocol != null && !requestingProtocol.equals(url.getProtocol())) |
| return false; |
| if (requestingProtocol == null && url.getProtocol() != null) |
| return false; |
| |
| if (requestingScheme != null && !requestingScheme.equals(scheme)) |
| return false; |
| if (requestingScheme == null && scheme != null) |
| return false; |
| |
| if (requestingHostName != null && !requestingHostName.equals(url.getHost())) |
| return false; |
| if (requestingHostName == null && url.getHost() != null) |
| return false; |
| |
| return true; |
| } |
| |
| /* |
| * returns a map that contains the userid and the password |
| * or <code>null</code> if the dialog has been cancelled |
| */ |
| private Map promptForPassword(URL resourceUrl, String realm) { |
| |
| Map result = null; |
| Shell shell = new Shell(); |
| UserValidationDialog ui = new UserValidationDialog(shell, resourceUrl, realm, ""); //$NON-NLS-1$ |
| ui.setUsernameMutable(true); |
| ui.setBlockOnOpen(true); |
| ui.open(); |
| |
| boolean isCancelled = ui.getReturnCode() == UserValidationDialog.CANCEL; |
| if (!isCancelled) { |
| result = new HashMap(); |
| result.put(INFO_USERNAME, ui.getUserid()); |
| result.put(INFO_PASSWORD, ui.getPassword()); |
| } |
| shell.dispose(); |
| |
| return result; |
| } |
| |
| /* |
| * @see Authenticator#getPasswordAuthentication() |
| */ |
| protected PasswordAuthentication getPasswordAuthentication() { |
| |
| try { |
| String hostName = getRequestingHost() != null ? getRequestingHost() : UNKNOWN_HOST; |
| URL url = new URL(getRequestingProtocol(), hostName, getRequestingPort(), ""); //$NON-NLS-1$ |
| Map map = retrievePasswordAuthentication(url); |
| |
| String username = null; |
| String password = null; |
| |
| if (map != null) { |
| username = (String) map.get(INFO_USERNAME); |
| password = (String) map.get(INFO_PASSWORD); |
| } |
| |
| if (username != null && password != null) { |
| return new PasswordAuthentication(username, password.toCharArray()); |
| } else { |
| return null; |
| } |
| |
| } catch (MalformedURLException e) { |
| IStatus status = Utilities.newCoreException("", e).getStatus(); //$NON-NLS-1$ |
| UpdateUI.log(status, false); |
| } |
| return new PasswordAuthentication("", new char[] { ' ' }); //$NON-NLS-1$ |
| } |
| |
| /* |
| * |
| */ |
| private Map retrievePasswordAuthentication(URL url) { |
| |
| if (equalsPreviousRequest(url,getRequestingPrompt(),getRequestingScheme())) { |
| // same request, the userid/password was wrong |
| // or user cancelled. force a refresh |
| if (savedPasswordAuthentication != null) |
| // only prompt if the user didn't cancel |
| savedPasswordAuthentication = requestAuthenticationInfo(url, requestingPrompt, requestingScheme); |
| } else { |
| // save state |
| requestingPort = getRequestingPort(); |
| requestingPrompt = getRequestingPrompt(); |
| requestingProtocol = getRequestingProtocol(); |
| requestingScheme = getRequestingScheme(); |
| requestingHostName = getRequestingHost() != null ? getRequestingHost() : UNKNOWN_HOST; |
| savedPasswordAuthentication = Platform.getAuthorizationInfo(url, requestingPrompt, requestingScheme); |
| if (savedPasswordAuthentication == null) { |
| savedPasswordAuthentication = requestAuthenticationInfo(url, requestingPrompt, requestingScheme); |
| } |
| } |
| return savedPasswordAuthentication; |
| } |
| |
| } |