View | Details | Raw Unified | Return to bug 379787 | Differences between
and this patch

Collapse All | Expand All

(-)a/rse/plugins/org.eclipse.rse.core/src/org/eclipse/rse/core/PasswordPersistenceManager.java (-44 / +71 lines)
Lines 1-5 Link Here
1
/********************************************************************************
1
/********************************************************************************
2
 * Copyright (c) 2002, 2012 IBM Corporation and others. All rights reserved.
2
 * Copyright (c) 2002, 2013 IBM Corporation and others. All rights reserved.
3
 * This program and the accompanying materials are made available under the terms
3
 * This program and the accompanying materials are made available under the terms
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is
5
 * available at http://www.eclipse.org/legal/epl-v10.html
5
 * available at http://www.eclipse.org/legal/epl-v10.html
Lines 20-25 Link Here
20
 * Martin Oberhuber (Wind River) - [cleanup] Add API "since" Javadoc tags
20
 * Martin Oberhuber (Wind River) - [cleanup] Add API "since" Javadoc tags
21
 * David Dykstal (IBM) - [210474] Deny save password function missing
21
 * David Dykstal (IBM) - [210474] Deny save password function missing
22
 * David Dykstal (IBM) - [225320] Use equinox secure storage for passwords
22
 * David Dykstal (IBM) - [225320] Use equinox secure storage for passwords
23
 * David Dykstal (IBM) - [379787] Fix secure storage usage in org.eclipse.rse.tests
23
 ********************************************************************************/
24
 ********************************************************************************/
24
25
25
package org.eclipse.rse.core;
26
package org.eclipse.rse.core;
Lines 48-53 import org.osgi.framework.Bundle; Link Here
48
/**
49
/**
49
 * PasswordPersistenceManager manages the saving and retrieving of user IDs /
50
 * PasswordPersistenceManager manages the saving and retrieving of user IDs /
50
 * passwords to Equinox secure storage for registered system types.
51
 * passwords to Equinox secure storage for registered system types.
52
 * <p>
53
 * A PasswordPersistenceManager is sensitive to the "rse.enableSecureStoreAccess" property.
54
 * If absent it defaults to <code>true</code>.
55
 * If present then the value must be <code>true</code> to enable access to the secure store.
56
 * The following code disables access to the secure store.
57
 * <p>
58
 * <code>System.setProperty("rse.enableSecureStoreAccess", "false");</code> 
51
 * 
59
 * 
52
 * @noextend This class is not intended to be subclassed by clients.
60
 * @noextend This class is not intended to be subclassed by clients.
53
 * @noinstantiate This class is not intended to be instantiated by clients. Use
61
 * @noinstantiate This class is not intended to be instantiated by clients. Use
Lines 382-388 public class PasswordPersistenceManager { Link Here
382
390
383
	/**
391
	/**
384
	 * Returns the preferences node that matches the system type.
392
	 * Returns the preferences node that matches the system type.
385
	 * It will not return null but will create the node if it does not exist.
393
	 * It will only return null if secure store access is disallowed.
394
	 * If secure store access is allowed it will create the node if it does not exist.
386
	 * If the node does not previous exist then an attempt will be made
395
	 * If the node does not previous exist then an attempt will be made
387
	 * to migrate the values from the old map form to this newly created node
396
	 * to migrate the values from the old map form to this newly created node
388
	 * of the secure preferences tree.
397
	 * of the secure preferences tree.
Lines 390-403 public class PasswordPersistenceManager { Link Here
390
	 * @return the matching secure preferences node. 
399
	 * @return the matching secure preferences node. 
391
	 */
400
	 */
392
	private ISecurePreferences getNode(IRSESystemType systemType) {
401
	private ISecurePreferences getNode(IRSESystemType systemType) {
393
		String id = systemType.getId();
394
		ISecurePreferences preferences = SecurePreferencesFactory.getDefault();
395
		ISecurePreferences rseNode = preferences.node("org.eclipse.rse.core.security"); //$NON-NLS-1$
396
		ISecurePreferences systemTypeNode = null;
402
		ISecurePreferences systemTypeNode = null;
397
		if (!rseNode.nodeExists(id)) {
403
		String enableSecureStoreAccess = System.getProperty("rse.enableSecureStoreAccess", "true");  //$NON-NLS-1$//$NON-NLS-2$
398
			migrateMap(rseNode, id);
404
		if (enableSecureStoreAccess.equals("true")) { //$NON-NLS-1$
405
			String id = systemType.getId();
406
			ISecurePreferences preferences = SecurePreferencesFactory.getDefault();
407
			ISecurePreferences rseNode = preferences.node("org.eclipse.rse.core.security"); //$NON-NLS-1$
408
			if (!rseNode.nodeExists(id)) {
409
				migrateMap(rseNode, id);
410
			}
411
			systemTypeNode = rseNode.node(id);
399
		}
412
		}
400
		systemTypeNode = rseNode.node(id);
401
		return systemTypeNode;
413
		return systemTypeNode;
402
	}
414
	}
403
415
Lines 473-492 public class PasswordPersistenceManager { Link Here
473
	 * @return the number of passwords removed.
485
	 * @return the number of passwords removed.
474
	 */
486
	 */
475
	private int removePassword(IRSESystemType systemType, String hostName, String userId) {
487
	private int removePassword(IRSESystemType systemType, String hostName, String userId) {
488
		int result = 0;
476
		ISecurePreferences passwords = getNode(systemType);
489
		ISecurePreferences passwords = getNode(systemType);
477
		boolean respectCase = isUserIDCaseSensitive(systemType);
490
		if (passwords != null) {
478
		String keys[] = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, false);
491
			boolean respectCase = isUserIDCaseSensitive(systemType);
479
		if (keys.length == 0) {
492
			String keys[] = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, false);
480
			keys = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, true);
493
			if (keys.length == 0) {
481
		}
494
				keys = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, true);
482
		for (int i = 0; i < keys.length; i++) {
495
			}
483
			String key = keys[i];
496
			for (int i = 0; i < keys.length; i++) {
484
			basicRemove(passwords, key);
497
				String key = keys[i];
485
		}
498
				basicRemove(passwords, key);
486
		if (keys.length > 0) {
499
			}
487
			basicSave(passwords);
500
			if (keys.length > 0) {
501
				basicSave(passwords);
502
			}
503
			result = keys.length;
488
		}
504
		}
489
		return keys.length;
505
		return result;
490
	}
506
	}
491
	
507
	
492
	/**
508
	/**
Lines 502-515 public class PasswordPersistenceManager { Link Here
502
	private String findPassword(IRSESystemType systemType, String hostName, String userId) {
518
	private String findPassword(IRSESystemType systemType, String hostName, String userId) {
503
		String password = null;
519
		String password = null;
504
		ISecurePreferences passwords = getNode(systemType);
520
		ISecurePreferences passwords = getNode(systemType);
505
		boolean respectCase = isUserIDCaseSensitive(systemType);
521
		if (passwords != null) {
506
		String keys[] = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, false);
522
			boolean respectCase = isUserIDCaseSensitive(systemType);
507
		if (keys.length == 0) {
523
			String keys[] = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, false);
508
			keys = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, true);
524
			if (keys.length == 0) {
509
		}
525
				keys = getMatchingKeys(passwords.keys(), hostName, userId, respectCase, true);
510
		if (keys.length > 0) {
526
			}
511
			String key = keys[0];
527
			if (keys.length > 0) {
512
			password = basicGet(passwords, key);
528
				String key = keys[0];
529
				password = basicGet(passwords, key);
530
			}
513
		}
531
		}
514
		return password;
532
		return password;
515
	}
533
	}
Lines 522-533 public class PasswordPersistenceManager { Link Here
522
	 * @param hostName the name of the host we are examining for a password.
540
	 * @param hostName the name of the host we are examining for a password.
523
	 * @param userId the user id to find passwords for.
541
	 * @param userId the user id to find passwords for.
524
	 * @param password the password to save for this entry.
542
	 * @param password the password to save for this entry.
543
	 * @return RC_OK if the password was updated, RC_DENIED if the password was not updated.
525
	 */
544
	 */
526
	private void updatePassword(IRSESystemType systemType, String hostName, String userId, String password) {
545
	private int updatePassword(IRSESystemType systemType, String hostName, String userId, String password) {
546
		int result = RC_DENIED;
527
		ISecurePreferences passwords = getNode(systemType);
547
		ISecurePreferences passwords = getNode(systemType);
528
		String key = getKey(hostName, userId);
548
		if (passwords != null) {
529
		basicPut(passwords, key, password);
549
			String key = getKey(hostName, userId);
530
		basicSave(passwords);
550
			basicPut(passwords, key, password);
551
			basicSave(passwords);
552
			result = RC_OK;
553
		}
554
		return result;
531
	}
555
	}
532
	
556
	
533
	/**
557
	/**
Lines 551-558 public class PasswordPersistenceManager { Link Here
551
	 * @param info The signon information to store
575
	 * @param info The signon information to store
552
	 * @param overwrite Whether to overwrite any existing entry
576
	 * @param overwrite Whether to overwrite any existing entry
553
	 * @return
577
	 * @return
554
	 * 	RC_OK if the password was successfully stored
578
	 * RC_OK if the password was successfully stored
555
	 *  RC_ALREADY_EXISTS if the password already exists and overwrite was false
579
	 * RC_ALREADY_EXISTS if the password already exists and overwrite was false
580
	 * RC_DENIED if passwords may not be saved for this system type and host
556
	 */
581
	 */
557
	public int add(SystemSignonInformation info, boolean overwrite) {
582
	public int add(SystemSignonInformation info, boolean overwrite) {
558
		return add(info, overwrite, false);
583
		return add(info, overwrite, false);
Lines 587-593 public class PasswordPersistenceManager { Link Here
587
			}
612
			}
588
			String oldPassword = findPassword(systemType, hostName, userId);
613
			String oldPassword = findPassword(systemType, hostName, userId);
589
			if (oldPassword == null || (overwrite && !newPassword.equals(oldPassword))) {
614
			if (oldPassword == null || (overwrite && !newPassword.equals(oldPassword))) {
590
				updatePassword(systemType, hostName, userId, newPassword);
615
				result = updatePassword(systemType, hostName, userId, newPassword);
591
			} else if (oldPassword != null) {
616
			} else if (oldPassword != null) {
592
				result = RC_ALREADY_EXISTS;
617
				result = RC_ALREADY_EXISTS;
593
			}
618
			}
Lines 629-635 public class PasswordPersistenceManager { Link Here
629
	 * @param systemType the IRSESystemType instance to find a password for.
654
	 * @param systemType the IRSESystemType instance to find a password for.
630
	 * @param hostName the name of the host we are examining for a password.
655
	 * @param hostName the name of the host we are examining for a password.
631
	 * @param userId the user id to find passwords for.
656
	 * @param userId the user id to find passwords for.
632
	 * @return the {@link SystemSignonInformation} for the specified criteria.
657
	 * @return the {@link SystemSignonInformation} for the specified criteria or null if no such password can be found.
633
	 */
658
	 */
634
	public SystemSignonInformation find(IRSESystemType systemType, String hostName, String userId) {
659
	public SystemSignonInformation find(IRSESystemType systemType, String hostName, String userId) {
635
		return find(systemType, hostName, userId, true);
660
		return find(systemType, hostName, userId, true);
Lines 644-650 public class PasswordPersistenceManager { Link Here
644
	 * @param hostName the name of the host we are examining for a password.
669
	 * @param hostName the name of the host we are examining for a password.
645
	 * @param userId the user id to find passwords for.
670
	 * @param userId the user id to find passwords for.
646
	 * @param checkDefault true if the default system type should be checked if the specified system type is not found
671
	 * @param checkDefault true if the default system type should be checked if the specified system type is not found
647
	 * @return the {@link SystemSignonInformation} for the specified criteria.
672
	 * @return the {@link SystemSignonInformation} for the specified criteria or null if no such password can be found.
648
	 */
673
	 */
649
	public SystemSignonInformation find(IRSESystemType systemType, String hostName, String userId, boolean checkDefault) {
674
	public SystemSignonInformation find(IRSESystemType systemType, String hostName, String userId, boolean checkDefault) {
650
		SystemSignonInformation result = null;
675
		SystemSignonInformation result = null;
Lines 729-741 public class PasswordPersistenceManager { Link Here
729
		for (int i = 0; i < systemTypes.length; i++) {
754
		for (int i = 0; i < systemTypes.length; i++) {
730
			IRSESystemType systemType = systemTypes[i];
755
			IRSESystemType systemType = systemTypes[i];
731
			ISecurePreferences node = getNode(systemType);
756
			ISecurePreferences node = getNode(systemType);
732
			String[] keys = node.keys();
757
			if (node != null) {
733
			for (int j = 0; j < keys.length; j++) {
758
				String[] keys = node.keys();
734
				String key = keys[j];
759
				for (int j = 0; j < keys.length; j++) {
735
				String hostName = getHostNameFromKey(key);
760
					String key = keys[j];
736
				String userId = getUserIdFromKey(key);
761
					String hostName = getHostNameFromKey(key);
737
				SystemSignonInformation info = new SystemSignonInformation(hostName, userId, systemType);
762
					String userId = getUserIdFromKey(key);
738
				savedUserIDs.add(info);
763
					SystemSignonInformation info = new SystemSignonInformation(hostName, userId, systemType);
764
					savedUserIDs.add(info);
765
				}
739
			}
766
			}
740
		}
767
		}
741
		return savedUserIDs;
768
		return savedUserIDs;
(-)a/rse/tests/org.eclipse.rse.tests/src/org/eclipse/rse/tests/core/passwords/PasswordsTest.java (-12 / +72 lines)
Lines 1-15 Link Here
1
/********************************************************************************
1
/********************************************************************************
2
 * Copyright (c) 2008, 2012 IBM Corporation and others. All rights reserved.
2
 * Copyright (c) 2008, 2013 IBM Corporation and others. All rights reserved.
3
 * This program and the accompanying materials are made available under the terms
3
 * This program and the accompanying materials are made available under the terms
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is
4
 * of the Eclipse Public License v1.0 which accompanies this distribution, and is
5
 * available at http://www.eclipse.org/legal/epl-v10.html
5
 * available at http://www.eclipse.org/legal/epl-v10.html
6
 *
6
 *
7
 * Contributors:
7
 * Contributors:
8
 * David Dykstal (IBM) - [210474] Deny save password function missing
8
 * David Dykstal (IBM) - [210474] Deny save password function missing
9
 * David Dykstal (IBM) - [379787] Fix secure storage usage in org.eclipse.rse.tests
9
 ********************************************************************************/
10
 ********************************************************************************/
10
11
11
package org.eclipse.rse.tests.core.passwords;
12
package org.eclipse.rse.tests.core.passwords;
12
13
14
import java.util.List;
15
13
import org.eclipse.rse.core.IRSESystemType;
16
import org.eclipse.rse.core.IRSESystemType;
14
import org.eclipse.rse.core.PasswordPersistenceManager;
17
import org.eclipse.rse.core.PasswordPersistenceManager;
15
import org.eclipse.rse.core.RSEPreferencesManager;
18
import org.eclipse.rse.core.RSEPreferencesManager;
Lines 28-33 public class PasswordsTest extends RSECoreTestCase { Link Here
28
	 */
31
	 */
29
	protected void setUp() throws Exception {
32
	protected void setUp() throws Exception {
30
		super.setUp();
33
		super.setUp();
34
//		System.setProperty("rse.enableSecureStoreAccess", "false");
31
	}
35
	}
32
36
33
	/* (non-Javadoc)
37
	/* (non-Javadoc)
Lines 39-46 public class PasswordsTest extends RSECoreTestCase { Link Here
39
43
40
	public void testAddRemove() {
44
	public void testAddRemove() {
41
		//-test-author-:DavidDykstal
45
		//-test-author-:DavidDykstal
42
		if (isTestDisabled())
46
		if (isTestDisabled()) return;
43
			return;
47
		if ("false".equals(System.getProperty("rse.enableSecureStoreAccess"))) return;
44
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_UNIX_ID);
48
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_UNIX_ID);
45
		IRSESystemType defaultSystemType = PasswordPersistenceManager.DEFAULT_SYSTEM_TYPE;
49
		IRSESystemType defaultSystemType = PasswordPersistenceManager.DEFAULT_SYSTEM_TYPE;
46
		String hostAddress = "somesystem.mycompany.com";
50
		String hostAddress = "somesystem.mycompany.com";
Lines 93-100 public class PasswordsTest extends RSECoreTestCase { Link Here
93
97
94
	public void testSaveDenial() {
98
	public void testSaveDenial() {
95
		//-test-author-:DavidDykstal
99
		//-test-author-:DavidDykstal
96
		if (isTestDisabled())
100
		if (isTestDisabled()) return;
97
			return;
101
		if ("false".equals(System.getProperty("rse.enableSecureStoreAccess"))) return;
98
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_UNIX_ID);
102
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_UNIX_ID);
99
		String hostAddress = "somesystem.mycompany.com";
103
		String hostAddress = "somesystem.mycompany.com";
100
		boolean deny = RSEPreferencesManager.getDenyPasswordSave(systemType, hostAddress);
104
		boolean deny = RSEPreferencesManager.getDenyPasswordSave(systemType, hostAddress);
Lines 136-143 public class PasswordsTest extends RSECoreTestCase { Link Here
136
140
137
	public void testMigration() {
141
	public void testMigration() {
138
		//-test-author-:DavidDykstal
142
		//-test-author-:DavidDykstal
139
		if (isTestDisabled())
143
		if (isTestDisabled()) return;
140
			return;
144
		if ("false".equals(System.getProperty("rse.enableSecureStoreAccess"))) return;
141
145
142
		// Setup
146
		// Setup
143
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_LOCAL_ID);
147
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_LOCAL_ID);
Lines 167-177 public class PasswordsTest extends RSECoreTestCase { Link Here
167
		}
171
		}
168
172
169
	}
173
	}
170
174
	
171
	public void testAliasing() {
175
	public void testAliasing() {
172
		//-test-author-:DavidDykstal
176
		//-test-author-:DavidDykstal
173
		if (isTestDisabled())
177
		if (isTestDisabled()) return;
174
			return;
178
		if ("false".equals(System.getProperty("rse.enableSecureStoreAccess"))) return;
175
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_LOCAL_ID);
179
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_LOCAL_ID);
176
		PasswordPersistenceManager ppm = PasswordPersistenceManager.getInstance();
180
		PasswordPersistenceManager ppm = PasswordPersistenceManager.getInstance();
177
		ppm.add(new SystemSignonInformation("LOUDHOST.mycompany.com", "thatguy", "abc", systemType), true, false);
181
		ppm.add(new SystemSignonInformation("LOUDHOST.mycompany.com", "thatguy", "abc", systemType), true, false);
Lines 187-199 public class PasswordsTest extends RSECoreTestCase { Link Here
187
	}
191
	}
188
	
192
	
189
	public void testBadArgs() {
193
	public void testBadArgs() {
190
		if (isTestDisabled())
194
		if (isTestDisabled()) return;
191
			return;
195
		if ("false".equals(System.getProperty("rse.enableSecureStoreAccess"))) return;
192
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_LOCAL_ID);
196
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_LOCAL_ID);
193
		PasswordPersistenceManager ppm = PasswordPersistenceManager.getInstance();
197
		PasswordPersistenceManager ppm = PasswordPersistenceManager.getInstance();
194
		ppm.add(new SystemSignonInformation("myhost.mycompany.com", "me", "password", systemType), true, false);
198
		ppm.add(new SystemSignonInformation("myhost.mycompany.com", "me", "password", systemType), true, false);
195
		SystemSignonInformation info = ppm.find(systemType, "myhost.mycompany.com", null);
199
		SystemSignonInformation info = ppm.find(systemType, "myhost.mycompany.com", null);
196
		assertNull(info);
200
		assertNull(info);
197
	}
201
	}
202
203
	public void testDisabledSecureStore() {
204
		//-test-author-:DavidDykstal
205
		if (isTestDisabled()) return;
206
		String key = "rse.enableSecureStoreAccess";
207
		String valueOnEntry = System.getProperty(key);
208
		System.setProperty(key, "false");
209
		PasswordPersistenceManager ppm = PasswordPersistenceManager.getInstance();
210
		IRSESystemType systemType = RSECoreRegistry.getInstance().getSystemType(IRSESystemType.SYSTEMTYPE_UNIX_ID);
211
		String hostAddress = "somesystem.mycompany.com";
212
		String password = "password";
213
		String userId = "me";
214
		SystemSignonInformation info = new SystemSignonInformation(hostAddress, userId, password, systemType);
215
	
216
		// try saving and retrieving a password
217
		int result = ppm.add(info, true);
218
		assertEquals("result of first add was not RC_DENIED", PasswordPersistenceManager.RC_DENIED, result);
219
		result = ppm.add(info, true, true);
220
		assertEquals("result of second add was not RC_DENIED", PasswordPersistenceManager.RC_DENIED, result);
221
		SystemSignonInformation returnedInfo = ppm.find(systemType, hostAddress, userId);
222
		assertNull("signon info was found and should not be", returnedInfo);
223
		
224
		// test passwords for existence
225
		assertFalse("found signon information where none should exist (1)", ppm.passwordExists(systemType, hostAddress, userId));
226
		assertFalse("found signon information where none should exist (2)", ppm.passwordExists(systemType, hostAddress, userId, false));
227
		assertFalse("found signon information where none should exist (3)", ppm.passwordExists(systemType, hostAddress, userId, true));
198
	
228
	
229
		// try finding password info
230
		returnedInfo = ppm.find(systemType, hostAddress, userId);
231
		assertNull("signon info was found and should not be (1)", returnedInfo);
232
		returnedInfo = ppm.find(systemType, hostAddress, userId, false);
233
		assertNull("signon info was found but should not be (2)", returnedInfo);
234
		returnedInfo = ppm.find(systemType, hostAddress, userId, true);
235
		assertNull("signon info was found but should not be (3)", returnedInfo);
236
		
237
		// try removal
238
		ppm.remove(info);
239
		ppm.remove(systemType, hostAddress, userId);
240
		assertEquals("passwords were removed but none should be (2)", 0, ppm.remove(systemType, hostAddress));
241
		
242
		// get system types
243
		IRSESystemType[] systemTypes = ppm.getRegisteredSystemTypes();
244
		assertNotNull("returned system types is null", systemTypes);
245
		assertTrue("no system types were found", systemTypes.length > 0);
246
		
247
		// get saved user ids
248
		@SuppressWarnings("rawtypes")
249
		List userInfo = ppm.getSavedUserIDs();
250
		assertTrue("user info was found where none should exist", userInfo.size() == 0);
251
		
252
		if (valueOnEntry == null) {
253
			System.clearProperty(key);
254
		} else {
255
			System.setProperty(key, valueOnEntry);
256
		}
257
	}
258
199
}
259
}

Return to bug 379787