diff --git a/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF
index fc632b6fb0d..38cd455ebb3 100644
--- a/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF
+++ b/rse/plugins/org.eclipse.rse.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.rse.core;singleton:=true
-Bundle-Version: 3.2.100.qualifier
+Bundle-Version: 3.3.0.qualifier
Bundle-Activator: org.eclipse.rse.core.RSECorePlugin
Bundle-Localization: plugin
Require-Bundle: org.eclipse.core.runtime,
diff --git a/rse/plugins/org.eclipse.rse.core/pom.xml b/rse/plugins/org.eclipse.rse.core/pom.xml
index 6a3eaa3fdc1..7eedba206c2 100644
--- a/rse/plugins/org.eclipse.rse.core/pom.xml
+++ b/rse/plugins/org.eclipse.rse.core/pom.xml
@@ -10,6 +10,6 @@
org.eclipse.tm
org.eclipse.rse.core
- 3.2.100-SNAPSHOT
+ 3.3.0-SNAPSHOT
eclipse-plugin
diff --git a/rse/plugins/org.eclipse.rse.core/src/org/eclipse/rse/core/PasswordPersistenceManager.java b/rse/plugins/org.eclipse.rse.core/src/org/eclipse/rse/core/PasswordPersistenceManager.java
index 87fda795404..589dc860468 100644
--- a/rse/plugins/org.eclipse.rse.core/src/org/eclipse/rse/core/PasswordPersistenceManager.java
+++ b/rse/plugins/org.eclipse.rse.core/src/org/eclipse/rse/core/PasswordPersistenceManager.java
@@ -23,20 +23,25 @@
package org.eclipse.rse.core;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.security.storage.ISecurePreferences;
+import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
+import org.eclipse.equinox.security.storage.StorageException;
import org.eclipse.rse.core.model.SystemSignonInformation;
import org.eclipse.rse.internal.core.RSECoreMessages;
+import org.osgi.framework.Bundle;
/**
* PasswordPersistenceManager manages the saving and retrieving of user ID /
@@ -54,24 +59,23 @@ public class PasswordPersistenceManager {
*/
private static class DefaultSystemType extends AbstractRSESystemType implements IRSESystemType {
private static final String DEFAULT_ID = "DEFAULT"; //$NON-NLS-1$
-
+
private DefaultSystemType() {
super(DEFAULT_ID, DEFAULT_ID, RSECoreMessages.DefaultSystemType_Label, null, null);
}
-
+
public String getId() {
- //TODO consider a space character at the beginning to ensure uniqueness
return DEFAULT_ID;
}
-
+
public String[] getSubsystemConfigurationIds() {
return null;
}
-
+
public Object getAdapter(Class adapter) {
return null;
}
-
+
public boolean isEnabled() {
return true;
}
@@ -91,8 +95,8 @@ public class PasswordPersistenceManager {
public static final int RC_DENIED = 2;
public static final int RC_ERROR = -1;
- // Default System Type, on a lookup if the specified system type and hostname is not found
- // then the call will automatically lookup the default system type and hostname
+ // Default System Type, on a lookup if the specified system type and host name is not found
+ // then the call will automatically lookup the default system type and host name
public static final IRSESystemType DEFAULT_SYSTEM_TYPE = new DefaultSystemType();
// Default user name
@@ -109,23 +113,126 @@ public class PasswordPersistenceManager {
public static final synchronized PasswordPersistenceManager getInstance() {
if (_instance == null) {
_instance = new PasswordPersistenceManager();
- _instance.initExtensions();
+ _instance.initializeSystemTypes();
}
return _instance;
}
/**
- * Inner class used for storing registered system types
+ * Tests the existence of the Eclipse keyring API by looking for installation of the bundle containing
+ * the API.
+ * @return true if the API is installed.
+ */
+ private static boolean isAuthorizationCompatabilityInstalled() {
+ boolean result = false;
+ Bundle authorizationBundle = Platform.getBundle("org.eclipse.core.runtime.compatability.auth"); //$NON-NLS-1$
+ if (authorizationBundle == null) {
+ IStatus status = new Status(IStatus.INFO, RSECorePlugin.PLUGIN_ID, "Saved passwords are not available for migration to secure storage. Deprecated authorization classes (org.eclipse.core.runtime.compatability.auth) are not installed."); //$NON-NLS-1$
+ RSECorePlugin.getDefault().getLog().log(status);
+ } else {
+ result = true;
+ }
+ return result;
+ }
+
+ /**
+ * Examine the preferences to see if password saving is allowed.
+ * @param systemType The system type to check
+ * @param hostName The host name to check
+ * @return true if we are allow to save password for this system type and host
+ */
+ private static boolean isSaveAllowed(IRSESystemType systemType, String hostName) {
+ boolean allowed = !RSEPreferencesManager.getDenyPasswordSave(systemType, hostName);
+ return allowed;
+ }
+
+ /**
+ * Build the key to lookup the password for a specific
+ * user ID and host name
+ * @param hostName the name of the host
+ * @param userId the name of the user
+ * @return a key composed of the host and user name
+ */
+ private static String getKey(String hostName, String userId) {
+ StringBuffer buffer = new StringBuffer(hostName);
+ buffer.append("//"); //$NON-NLS-1$
+ buffer.append(userId);
+ return buffer.toString();
+ }
+
+ /**
+ * Retrieve a host name from a key.
+ * @param passwordKey the key to examine for a host
+ * @return the host name from the key
+ */
+ private static String getHostNameFromKey(String passwordKey) {
+ int sepIndex = passwordKey.indexOf("//"); //$NON-NLS-1$
+ return passwordKey.substring(0, sepIndex);
+ }
+
+ /**
+ * Retrieve a user id from a key.
+ * @param passwordKey the key to examine for a host
+ * @return the user id from the key
+ */
+ private static String getUserIdFromKey(String passwordKey) {
+ int sepIndex = passwordKey.indexOf("//"); //$NON-NLS-1$
+ return passwordKey.substring(sepIndex + 2, passwordKey.length());
+ }
+
+ /**
+ * Given an array of keys into a password node for a system type return the ones that match the host name and user id criteria.
+ * Fuzzy matching will match hosts if one is a prefix of the other and they both resolve to the same network location.
+ * @param keys the original array of keys
+ * @param hostName the host name to match.
+ * @param userId the userId to match. This may be null. If it is then all users for this host name are matched.
+ * @param respectCase true if case must be respected to match a user id.
+ * @param fuzzy true if a fuzzy host name match is desired.
+ * @return a new array of keys from the original array that match the criteria.
+ */
+ private static String[] getMatchingKeys(String[] keys, String hostName, String userId, boolean respectCase, boolean fuzzy) {
+ List selectedKeys = new ArrayList();
+ for (int i = 0; i < keys.length; i++) {
+ String key = keys[i];
+ String keyHostName = getHostNameFromKey(key);
+ String keyUserId = getUserIdFromKey(key);
+ boolean match = (userId == null || (respectCase ? userId.equals(keyUserId) : userId.equalsIgnoreCase(keyUserId)));
+ if (match) {
+ if (fuzzy) {
+ if (hostName.startsWith(keyHostName) || keyHostName.startsWith(hostName)) {
+ String khn = RSECorePlugin.getQualifiedHostName(keyHostName);
+ String phn = RSECorePlugin.getQualifiedHostName(hostName);
+ match = khn.equalsIgnoreCase(phn);
+ } else {
+ match = false;
+ }
+ } else {
+ match = hostName.equals(keyHostName);
+ }
+ }
+ if (match) {
+ selectedKeys.add(key);
+ }
+ }
+ String[] result = new String[selectedKeys.size()];
+ selectedKeys.toArray(result);
+ return result;
+ }
+
+ /**
+ * Inner class used for storing registered system types.
+ * In particular this class can be used to determine whether a given
+ * system type supports case-sensitive user id
*/
private class RegisteredSystemType {
private IRSESystemType _systemType;
private boolean _userIDCaseSensitive;
-
+
protected RegisteredSystemType(IRSESystemType systemType, boolean caseSensitive) {
_systemType = systemType;
_userIDCaseSensitive = caseSensitive;
}
-
+
/**
* Returns the system type.
* @return the system type.
@@ -133,7 +240,7 @@ public class PasswordPersistenceManager {
public IRSESystemType getSystemType() {
return _systemType;
}
-
+
/**
* Returns whether the user ID is case sensitive.
* @return true
if the user ID is case sensitive, false
otherwise.
@@ -143,193 +250,236 @@ public class PasswordPersistenceManager {
}
}
- // New URL to store password map
- private String newURL = null;
-
- /*
- * Instance variables
- */
+ private String mapLocation = null;
private RegisteredSystemType[] systemTypes;
/**
- * Singleton so private constructor
+ * Singleton so this is a private constructor
*/
private PasswordPersistenceManager() {
String userName = System.getProperty("user.name"); //$NON-NLS-1$
-
if (userName == null) {
userName = DEFAULT_USER_NAME;
}
-
- newURL = SERVER_URL + userName;
+ if (isAuthorizationCompatabilityInstalled()) {
+ mapLocation = SERVER_URL + userName;
+ }
}
-
- /*
- * initialization - register system types
+
+ /**
+ * Examine the system type extensions and construct an array of installed system types.
*/
- private void initExtensions() {
+ private void initializeSystemTypes() {
IRSESystemType[] sysTypes = RSECorePlugin.getTheCoreRegistry().getSystemTypes();
systemTypes = new RegisteredSystemType[sysTypes.length];
-
for (int i = 0; i < sysTypes.length; i++) {
systemTypes[i] = new RegisteredSystemType(sysTypes[i], true);
}
}
/**
- * Helper class for building the key to lookup the password for a specific
- * userid and hostname in the Map
+ * Retrieve the old password map from the Eclipse keyring for the specified system type.
+ * This uses deprecated APIs only if those APIs are installed.
+ * This should only be used to retrieve maps for migration to the new secure-storage API.
+ * @param systemTypeId the id of the system type to retrieve the map for
+ * @return a Map that maps keys composed of host names and user ids to passwords for this particular
+ * system type. Returns null if the API is not installed or there is no map found.
*/
- private String getPasswordKey(String hname, String userid) {
- String hostname = hname;//RSEUIPlugin.getQualifiedHostName(hname);
- StringBuffer buffer = new StringBuffer(hostname);
- buffer.append("//"); //$NON-NLS-1$
- buffer.append(userid);
- return buffer.toString();
+ private Map getMap(String systemTypeId) {
+ Map passwordMap = null;
+ if (mapLocation != null) {
+ try {
+ URL serverURL = new URL(mapLocation);
+ passwordMap = Platform.getAuthorizationInfo(serverURL, systemTypeId, AUTH_SCHEME);
+ if (passwordMap == null) {
+ URL oldServerURL1 = new URL(SERVER_URL + ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString());
+ passwordMap = Platform.getAuthorizationInfo(oldServerURL1, systemTypeId, AUTH_SCHEME);
+ if (passwordMap == null) {
+ URL oldServerURL2 = new URL(SERVER_URL);
+ passwordMap = Platform.getAuthorizationInfo(oldServerURL2, systemTypeId, AUTH_SCHEME);
+ }
+ }
+ } catch (MalformedURLException e) {
+ RSECorePlugin.getDefault().getLogger().logError("PasswordPersistenceManager.getPasswordMap", e); //$NON-NLS-1$
+ }
+ }
+ return passwordMap;
}
- private String getHostnameFromPasswordKey(String passwordKey) {
- int sepIndex = passwordKey.indexOf("//"); //$NON-NLS-1$
- return passwordKey.substring(0, sepIndex);
- }
-
- private String getUserIdFromPasswordKey(String passwordKey) {
- int sepIndex = passwordKey.indexOf("//"); //$NON-NLS-1$
- return passwordKey.substring(sepIndex + 2, passwordKey.length());
- }
-
- /*
- * Retrieve the password map from the keyring for the specified system type
+ /**
+ * Migrates passwords stored in their old map form into a node of the
+ * secure preferences tree. The old map is left intact.
+ * @param parentNode the parent node of the new node for a system type that will
+ * hold all the passwords for that system type. The new node is created under this
+ * parent node.
+ * @param systemTypeId the id of this system type to create. The node is named with
+ * this identifier.
*/
- private Map getPasswordMap(IRSESystemType systemType) {
- Map passwords = null;
- String systemTypeId = systemType.getId();
-
+ private void migrateMap(ISecurePreferences parentNode, String systemTypeId) {
+ ISecurePreferences systemTypeNode = parentNode.node(systemTypeId);
+ Map passwordMap = getMap(systemTypeId);
+ if (passwordMap != null) {
+ Set entries = passwordMap.entrySet();
+ for (Iterator z = entries.iterator(); z.hasNext();) {
+ Map.Entry entry = (Map.Entry) z.next();
+ String key = (String) entry.getKey();
+ String value = (String) entry.getValue();
+ basicPut(systemTypeNode, key, value);
+ }
+ }
+ basicSave(systemTypeNode);
+ }
+
+ /**
+ * Returns the preferences node that matches the system type.
+ * It will not return null but will create the node if it does not exist.
+ * If the node does not previous exist then an attempt will be made
+ * to migrate the values from the old map form to this newly created node
+ * of the secure preferences tree.
+ * @param systemType the system type to retrieve
+ * @return the matching secure preferences node.
+ */
+ private ISecurePreferences getNode(IRSESystemType systemType) {
+ String id = systemType.getId();
+ ISecurePreferences preferences = SecurePreferencesFactory.getDefault();
+ ISecurePreferences rseNode = preferences.node("org.eclipse.rse.core.security"); //$NON-NLS-1$
+ ISecurePreferences systemTypeNode = null;
+ if (!rseNode.nodeExists(id)) {
+ migrateMap(rseNode, id);
+ }
+ systemTypeNode = rseNode.node(id);
+ return systemTypeNode;
+ }
+
+ /**
+ * Saves a node of the secure preferences tree.
+ * Logs an error if this cannot be saved for some reason.
+ * @param node the node to save.
+ */
+ private void basicSave(ISecurePreferences node) {
try {
- URL serverURL = new URL(newURL);
- passwords = Platform.getAuthorizationInfo(serverURL, systemTypeId, AUTH_SCHEME);
-
- // if no passwords found with new URL, check old URL
- if (passwords == null) {
-
- URL oldServerURL1 = new URL(SERVER_URL + ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString());
- passwords = Platform.getAuthorizationInfo(oldServerURL1, systemTypeId, AUTH_SCHEME);
-
- // passwords found, so migrate to using new URL
- if (passwords != null) {
- savePasswordMap(systemTypeId, passwords);
- }
- // if still no passwords found, check with even older URL
- else {
- URL oldServerURL2 = new URL(SERVER_URL);
- passwords = Platform.getAuthorizationInfo(oldServerURL2, systemTypeId, AUTH_SCHEME);
-
- // passwords found, so migrate to using new URL
- if (passwords != null) {
- savePasswordMap(systemTypeId, passwords);
- }
- }
- }
- } catch (MalformedURLException e) {
- RSECorePlugin.getDefault().getLogger().logError("PasswordPersistenceManager.getPasswordMap", e); //$NON-NLS-1$
+ node.flush();
+ } catch (IOException e) {
+ IStatus status = new Status(IStatus.ERROR, RSECorePlugin.PLUGIN_ID, "Unexpected error saving password.", e); //$NON-NLS-1$
+ RSECorePlugin.getDefault().getLog().log(status);
}
-
- return passwords;
}
-
- /*
- * Retrieve the password map from the keyring for the specified system type
+
+ /**
+ * Removes an entry from a node in the secure preferences tree.
+ * This entry is a password for a given host name and user id.
+ * @param node the node from which to remove the password entry.
+ * @param key the key consisting of a host name, user id pair
+ * @see #getKey(String, String)
*/
- private void savePasswordMap(String systemTypeId, Map passwords) {
+ private void basicRemove(ISecurePreferences node, String key) {
+ node.remove(key);
+ }
+
+ /**
+ * Finds a password in a secure preferences node given its key.
+ * Logs an error if this cannot be found for some malfunction of the storage mechanism.
+ * @param node the node in which to find the password entry.
+ * @param key the key consisting of a host name, user id pair
+ * @see #getKey(String, String)
+ * @return the password associated with this key or null if the
+ * entry was not found.
+ */
+ private String basicGet(ISecurePreferences node, String key) {
+ String value = null;
try {
- URL serverURL = new URL(newURL);
- Platform.flushAuthorizationInfo(serverURL, systemTypeId, AUTH_SCHEME);
- Platform.addAuthorizationInfo(serverURL, systemTypeId, AUTH_SCHEME, passwords);
- } catch (MalformedURLException e) {
- RSECorePlugin.getDefault().getLogger().logError("PasswordPersistenceManager.savePasswordMap", e); //$NON-NLS-1$
- } catch (CoreException e) {
- RSECorePlugin.getDefault().getLogger().logError("PasswordPersistenceManager.savePasswordMap", e); //$NON-NLS-1$
+ value = node.get(key, null);
+ } catch (StorageException e) {
+ IStatus status = new Status(IStatus.ERROR, RSECorePlugin.PLUGIN_ID, "Unexpected error retrieving password.", e); //$NON-NLS-1$
+ RSECorePlugin.getDefault().getLog().log(status);
+ }
+ return value;
+ }
+
+ /**
+ * Writes a password to a secure preferences node.
+ * Logs an error if this cannot be found for some malfunction of the storage mechanism.
+ * @param node the node in which to write the password entry.
+ * @param key the key consisting of a host name, user id pair
+ * @param value the password value to store for this key
+ * @see #getKey(String, String)
+ */
+ private void basicPut(ISecurePreferences node, String key, String value) {
+ try {
+ node.put(key, value, true);
+ } catch (StorageException e) {
+ IStatus status = new Status(IStatus.ERROR, RSECorePlugin.PLUGIN_ID, "Unexpected error updating password.", e); //$NON-NLS-1$
+ RSECorePlugin.getDefault().getLog().log(status);
}
}
- private boolean removeFromPasswordMap(Map passwords, String hostname, String userid) {
- boolean removed = false;
- String password = null;
-
- String passwordKey = getPasswordKey(hostname, userid);
- password = (String) passwords.get(passwordKey);
- if (password != null) {
- passwords.remove(passwordKey);
- removed = true;
- } else {
- String phostname = hostname.toUpperCase();
-
- // DKM - fallback for different case uids, hostnames or qualified/unqualified hostnames
- Iterator keys = passwords.keySet().iterator();
- while (keys.hasNext() && password == null) {
- String key = (String) keys.next();
- if (key.equalsIgnoreCase(passwordKey)) {
- password = (String) passwords.get(key);
- } else {
- String khostname = getHostnameFromPasswordKey(key).toUpperCase();
- String kuid = getUserIdFromPasswordKey(key);
- if (kuid.equalsIgnoreCase(userid)) {
- // uid matches, check if hosts are the same
- if (khostname.startsWith(phostname) || phostname.startsWith(khostname)) {
- String qkhost = RSECorePlugin.getQualifiedHostName(khostname);
- String qphost = RSECorePlugin.getQualifiedHostName(phostname);
- if (qkhost.equals(qphost)) {
- password = (String) passwords.get(key);
- }
- }
- }
- }
- if (password != null) {
- passwords.remove(key);
- removed = true;
-
- }
- }
+ /**
+ * Retrieves the password node for the given system type and removes password entries from that node.
+ * Removes only those that match the host name and user id exactly if one such entries exist.
+ * If no such entries exist then it will remove those for the host names that resolve to the same target as the specified host.
+ * @param systemType the IRSESystemType instance to remove passwords for.
+ * @param hostName the name of the host we are removing passwords for.
+ * @param userId the user id to remove passwords for. This may be null. If so then all users for this host name are affected.
+ * @return the number of passwords removed.
+ */
+ private int removePassword(IRSESystemType systemType, String hostName, String userId) {
+ ISecurePreferences passwords = getNode(systemType);
+ boolean respectCase = isUserIDCaseSensitive(systemType);
+ String keys[] = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, false);
+ if (keys.length == 0) {
+ keys = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, true);
}
- return removed;
-
+ for (int i = 0; i < keys.length; i++) {
+ String key = keys[i];
+ basicRemove(passwords, key);
+ }
+ if (keys.length > 0) {
+ basicSave(passwords);
+ }
+ return keys.length;
}
-
- private String getFromPasswordMap(Map passwords, String hostname, String userid) {
+
+ /**
+ * Retrieves the password node for the given system type and finds a password in that node.
+ * Initially looks only at those entries that match the host name and user id exactly.
+ * If no such entries exist then it will examine those for the host names that resolve to the same target as the specified host.
+ * @param systemType the IRSESystemType instance to find a password for.
+ * @param hostName the name of the host we are examining for a password.
+ * @param userId the user id to find passwords for.
+ * @return the first such password found that meets these criteria or null if no entry in this
+ * system type node matches the criteria.
+ */
+ private String findPassword(IRSESystemType systemType, String hostName, String userId) {
String password = null;
-
- String passwordKey = getPasswordKey(hostname, userid);
- password = (String) passwords.get(passwordKey);
- if (password != null) return password;
-
- String phostname = hostname.toUpperCase();
-
- // DKM - fallback for different case uids, hostnames or qualified/unqualified hostnames
- Iterator keys = passwords.keySet().iterator();
- while (keys.hasNext() && password == null) {
- String key = (String) keys.next();
- if (key.equalsIgnoreCase(passwordKey)) {
- password = (String) passwords.get(key);
- } else {
- String khostname = getHostnameFromPasswordKey(key).toUpperCase();
- String kuid = getUserIdFromPasswordKey(key);
- if (kuid.equalsIgnoreCase(userid)) {
- // uid matches, check if hosts are the same
- if (khostname.startsWith(phostname) || phostname.startsWith(khostname)) {
- String qkhost = RSECorePlugin.getQualifiedHostName(khostname);
- String qphost = RSECorePlugin.getQualifiedHostName(phostname);
- if (qkhost.equals(qphost)) {
- password = (String) passwords.get(key);
- }
- }
- }
- }
+ ISecurePreferences passwords = getNode(systemType);
+ boolean respectCase = isUserIDCaseSensitive(systemType);
+ String keys[] = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, false);
+ if (keys.length == 0) {
+ keys = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, true);
+ }
+ if (keys.length > 0) {
+ String key = keys[0];
+ password = basicGet(passwords, key);
}
-
return password;
-
}
+ /**
+ * Updates the password node for the given system type and finds a password in that node.
+ * Updates only that entry that matches the host name and user id exactly.
+ * If no such entries exist then it will add an entry for that host name and user id.
+ * @param systemType the IRSESystemType instance to find a password for.
+ * @param hostName the name of the host we are examining for a password.
+ * @param userId the user id to find passwords for.
+ * @param password the password to save for this entry.
+ */
+ private void updatePassword(IRSESystemType systemType, String hostName, String userId, String password) {
+ ISecurePreferences passwords = getNode(systemType);
+ String key = getKey(hostName, userId);
+ basicPut(passwords, key, password);
+ basicSave(passwords);
+ }
+
/**
* Add a password to the password database.
* This will not update the entry for the default system type
@@ -345,9 +495,9 @@ public class PasswordPersistenceManager {
/**
* Add a password to the password database.
- * @param info The signon information to store
- * @param overwrite If true then overwrite the existing entry for this systemtype, hostname, and userid.
- * @param updateDefault if true then set the entry for the default systemtype, hostname, and user ID, according to the overwrite setting.
+ * @param info The SystemSignonInformation to store
+ * @param overwrite If true then overwrite the existing entry for this system type, host name, and user id.
+ * @param updateDefault if true then set the entry for the default system type, host name, and user ID, according to the overwrite setting.
* @return
* RC_OK if the password was successfully stored.
* RC_ALREADY_EXISTS if the password already exists and overwrite was false
@@ -359,8 +509,7 @@ public class PasswordPersistenceManager {
String hostName = info.getHostname();
String userId = info.getUserId();
String newPassword = info.getPassword();
- boolean deny = RSEPreferencesManager.getDenyPasswordSave(systemType, hostName);
- if (!deny) {
+ if (isSaveAllowed(systemType, hostName)) {
if (!isUserIDCaseSensitive(systemType)) {
userId = userId.toUpperCase();
info.setUserId(userId);
@@ -371,22 +520,11 @@ public class PasswordPersistenceManager {
result = add(newInfo, overwrite, false);
}
}
- Map passwords = getPasswordMap(systemType);
- if (passwords == null) {
- passwords = new HashMap(5);
- }
- String oldPassword = getFromPasswordMap(passwords, hostName, userId);
- if (oldPassword != null) {
- if (overwrite) {
- removeFromPasswordMap(passwords, hostName, userId);
- } else {
- result = RC_ALREADY_EXISTS;
- }
- }
- if (result == RC_OK) {
- String passwordKey = getPasswordKey(hostName, userId);
- passwords.put(passwordKey, newPassword);
- savePasswordMap(systemType.getId(), passwords);
+ String oldPassword = findPassword(systemType, hostName, userId);
+ if (oldPassword == null || (overwrite && !newPassword.equals(oldPassword))) {
+ updatePassword(systemType, hostName, userId, newPassword);
+ } else if (oldPassword != null) {
+ result = RC_ALREADY_EXISTS;
}
} else {
result = RC_DENIED;
@@ -395,73 +533,76 @@ public class PasswordPersistenceManager {
}
/**
- * Check if a password entry exists for the specified system type, hostname
- * and userid.
+ * Determines if password entry exists for a given system type, host name, and user id.
+ * @param systemType the IRSESystemType instance to find a password for.
+ * @param hostName the name of the host we are examining for a password.
+ * @param userId the user id to find passwords for.
+ * @return true if a password exists that meets the search criteria.
*/
- public boolean passwordExists(IRSESystemType systemtype, String hostname, String userid) {
-
- return passwordExists(systemtype, hostname, userid, true);
+ public boolean passwordExists(IRSESystemType systemType, String hostName, String userId) {
+ return passwordExists(systemType, hostName, userId, true);
}
/**
- * Check if a password entry exists for the specified system type, hostname
- * and userid.
- *
- * @param systemtype The system type to check for.
- * @param hname The hostname to check for.
- * @param userid The user ID to check for.
+ * Determine if a password entry exists for the specified system type, host name, and user id.
+ * @param systemType the IRSESystemType instance to find a password for.
+ * @param hostName the name of the host we are examining for a password.
+ * @param userId the user id to find passwords for.
* @param checkDefault Whether or not to check for a default system type if the specified system type is not found.
+ * @return true if a password exists that meets the search criteria.
*/
- public boolean passwordExists(IRSESystemType systemtype, String hname, String userid, boolean checkDefault) {
- String hostname = hname;//RSEUIPlugin.getQualifiedHostName(hname);
- return (find(systemtype, hostname, userid) != null);
+ public boolean passwordExists(IRSESystemType systemType, String hostName, String userId, boolean checkDefault) {
+ SystemSignonInformation info = find(systemType, hostName, userId, checkDefault);
+ return (info != null);
}
/**
- * Find the password for the specified systemtype, hostname and userid.
- * If one is not found then the default system type is used.
- * The system type in the signon information returned may not be the same as the system type
- * specfied in the argument.
+ * Find the password for the specified system type, host name and user id.
+ * If one is not found then the default system type is also searched, thus
+ * the system type in the returned SystemSignonInformation may not be the same as the system type
+ * specified in the argument.
+ * @param systemType the IRSESystemType instance to find a password for.
+ * @param hostName the name of the host we are examining for a password.
+ * @param userId the user id to find passwords for.
+ * @return the {@link SystemSignonInformation} for the specified criteria.
*/
- public SystemSignonInformation find(IRSESystemType systemtype, String hostname, String userid) {
- return find(systemtype, hostname, userid, true);
+ public SystemSignonInformation find(IRSESystemType systemType, String hostName, String userId) {
+ return find(systemType, hostName, userId, true);
}
/**
- * Find the persisted password for the specified systemtype, hostname and userid.
- *
- * @param systemtype The system type to check for.
- * @param hname The hostname to check for.
- * @param userid The user ID to check for.
- * @param checkDefault Whether or not to check for a default system type if the specified system type is not found.
+ * Find the password for the specified system type, host name and user id.
+ * If one is not found then the default system type is also searched, thus
+ * the system type in the returned SystemSignonInformation may not be the same as the system type
+ * specified in the argument.
+ * @param systemType the IRSESystemType instance to find a password for.
+ * @param hostName the name of the host we are examining for a password.
+ * @param userId the user id to find passwords for.
+ * @param checkDefault true if the default system type should be checked if the specified system type is not found
+ * @return the {@link SystemSignonInformation} for the specified criteria.
*/
- public SystemSignonInformation find(IRSESystemType systemtype, String hname, String userid, boolean checkDefault) {
- String hostname = hname;//RSEUIPlugin.getQualifiedHostName(hname);
- // Convert userid to upper case if required
- if (!isUserIDCaseSensitive(systemtype) && userid != null) {
- userid = userid.toUpperCase();
+ public SystemSignonInformation find(IRSESystemType systemType, String hostName, String userId, boolean checkDefault) {
+ SystemSignonInformation result = null;
+ if (userId != null && !isUserIDCaseSensitive(systemType)) {
+ userId = userId.toUpperCase();
}
-
- Map passwords = getPasswordMap(systemtype);
-
- if (passwords != null) {
- String password = getFromPasswordMap(passwords, hostname, userid);
-
+ if (result == null) {
+ String password = findPassword(systemType, hostName, userId);
if (password != null) {
- return new SystemSignonInformation(hostname, userid, password, systemtype);
+ result = new SystemSignonInformation(hostName, userId, password, systemType);
}
}
-
- // yantzi: RSE6.2 check for default system type entry with this hostname and user ID
- if (checkDefault && !DEFAULT_SYSTEM_TYPE.equals(systemtype)) {
- return find(DEFAULT_SYSTEM_TYPE, hostname, userid, false);
+ if (result == null && checkDefault && !systemType.equals(DEFAULT_SYSTEM_TYPE)) {
+ String password = findPassword(DEFAULT_SYSTEM_TYPE, hostName, userId);
+ if (password != null) {
+ result = new SystemSignonInformation(hostName, userId, password, DEFAULT_SYSTEM_TYPE);
+ }
}
-
- return null;
+ return result;
}
/**
- * Remove the entry from the keyring that matches the systemtype, hostname and
+ * Remove the password entry that matches the system type, host name and
* user ID from the SystemSignonInfo parameter.
*/
public void remove(SystemSignonInformation info) {
@@ -469,127 +610,85 @@ public class PasswordPersistenceManager {
}
/**
- * Removes all passwords for a host name for a given system type. Use the
- * default system type explicitly to remove those entries.
- *
+ * Removes all passwords for a host name for a given system type.
+ * This does not remove entries for the default system type.
+ * The default system type must be explicitly stated to remove those entries.
* @param systemType The system type of the host
- * @param hostName The IP address of the host in canonical format
- * @return the number of passwords removed from the keyring
+ * @param hostName The IP address or name of the host in canonical format
+ * @return the number of passwords removed
* @since org.eclipse.rse.core 3.0
*/
public int remove(IRSESystemType systemType, String hostName) {
- Map passwords = getPasswordMap(systemType);
- int numberRemoved = 0;
- if (passwords != null) {
- String hostPrefix = hostName + "//"; //$NON-NLS-1$
- Set keys = passwords.keySet();
- for (Iterator z = keys.iterator(); z.hasNext();) {
- String key = (String) z.next();
- if (key.startsWith(hostPrefix)) {
- z.remove(); // safely removes the key and the entry from the map
- numberRemoved++;
- }
- }
- if (numberRemoved > 0) {
- savePasswordMap(systemType.getId(), passwords);
- }
- }
- return numberRemoved;
+ int result = removePassword(systemType, hostName, null);
+ return result;
}
/**
- * Removes all entries from the keyring that match the hostname, userid, and system type.
- * Use the default system type explicitly to remove those entries.
+ * Removes all entries that match the host name, user id, and system type.
+ * This does not remove entries for the default system type.
+ * The default system type must be explicitly stated to remove those entries.
* @param systemType the systemType
* @param hostName the connection name
- * @param userid the user id
+ * @param userId the user id
*/
- public void remove(IRSESystemType systemType, String hostName, String userid) {
- String hostname = hostName;//RSEUIPlugin.getQualifiedHostName(hname);
- // Convert userid to upper case if required
+ public void remove(IRSESystemType systemType, String hostName, String userId) {
if (!isUserIDCaseSensitive(systemType)) {
- userid = userid.toUpperCase();
- }
- Map passwords = getPasswordMap(systemType);
- if (passwords != null) {
- if (removeFromPasswordMap(passwords, hostname, userid)) {
- savePasswordMap(systemType.getId(), passwords);
- }
+ userId = userId.toUpperCase();
}
+ removePassword(systemType, hostName, userId);
}
/**
- * Retrieve the list of registered system types
+ * Retrieve the list of registered system types.
+ * This includes the default system type as well.
+ * @return an array of {@link IRSESystemType}.
*/
public IRSESystemType[] getRegisteredSystemTypes() {
- // yantzi: artemis 6.2, added default system type to list
IRSESystemType[] types = new IRSESystemType[systemTypes.length + 1];
-
types[0] = DEFAULT_SYSTEM_TYPE;
-
for (int i = 0; i < systemTypes.length; i++) {
types[i + 1] = systemTypes[i].getSystemType();
}
-
return types;
}
/**
- * Retrieve a list of the stored user IDs.
- *
+ * Retrieves a list of SystemSignonInformation instances that have been saved.
+ * These instances do not contain the saved passwords.
* @return List A list of the stored user IDs as SystemSignonInformation instances
* without the saved passwords.
*/
public List getSavedUserIDs() {
List savedUserIDs = new ArrayList();
- Map passwords;
- String key;
- int separator;
-
+ IRSESystemType[] systemTypes = getRegisteredSystemTypes();
for (int i = 0; i < systemTypes.length; i++) {
- passwords = getPasswordMap(systemTypes[i].getSystemType());
- if (passwords != null) {
- Iterator keys = passwords.keySet().iterator();
- while (keys.hasNext()) {
- key = (String) keys.next();
- separator = key.indexOf("//"); //$NON-NLS-1$
- savedUserIDs.add(new SystemSignonInformation(key.substring(0, separator), // hostname
- key.substring(separator + 2), // userid
- systemTypes[i].getSystemType())); // system type
- }
+ IRSESystemType systemType = systemTypes[i];
+ ISecurePreferences node = getNode(systemType);
+ String[] keys = node.keys();
+ for (int j = 0; j < keys.length; j++) {
+ String key = keys[j];
+ String hostName = getHostNameFromKey(key);
+ String userId = getUserIdFromKey(key);
+ SystemSignonInformation info = new SystemSignonInformation(hostName, userId, systemType);
+ savedUserIDs.add(info);
}
}
-
- // yantzi: RSE 6.2 Get DEFAULT system types too
- passwords = getPasswordMap(DEFAULT_SYSTEM_TYPE);
- if (passwords != null) {
- Iterator keys = passwords.keySet().iterator();
- while (keys.hasNext()) {
- key = (String) keys.next();
- separator = key.indexOf("//"); //$NON-NLS-1$
- savedUserIDs.add(new SystemSignonInformation(key.substring(0, separator), // hostname
- key.substring(separator + 2), // userid
- DEFAULT_SYSTEM_TYPE)); // system type
- }
- }
-
return savedUserIDs;
}
/**
- * Helper method for determining if system type uses case sensitive user IDs
+ * Helper method for determining if system type uses case sensitive user IDs.
+ * @return true if the system type treats user ids as case sensitive.
*/
public boolean isUserIDCaseSensitive(IRSESystemType systemType) {
- // First find the correct provider
+ boolean result = true;
for (int i = 0; i < systemTypes.length; i++) {
-
if (systemTypes[i].getSystemType().equals(systemType)) {
- return systemTypes[i].isUserIDCaseSensitive();
+ result = systemTypes[i].isUserIDCaseSensitive();
+ break;
}
}
-
- //Not found: Default system type is case sensitive
- return true;
+ return result;
}
}
\ No newline at end of file