/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.security.password; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.util.List; import org.apache.commons.io.FileUtils; import org.geoserver.data.test.SystemTestData; import org.geoserver.security.GeoServerSecurityTestSupport; import org.geoserver.security.auth.GeoServerRootAuthenticationProvider; import org.geoserver.security.validation.MasterPasswordChangeException; import org.geoserver.test.SystemTest; import org.geotools.data.DataUtilities; import org.junit.Test; import org.junit.experimental.categories.Category; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; //@TestSetup(run=TestSetupFrequency.REPEAT) @Category(SystemTest.class) public class MasterPasswordChangeTest extends GeoServerSecurityTestSupport { @Override protected void setUpSpring(List<String> springContextLocations) { super.setUpSpring(springContextLocations); springContextLocations.add( getClass().getResource(getClass().getSimpleName() + "-context.xml").toString()); } @Override protected void onSetUp(SystemTestData testData) throws Exception { super.onSetUp(testData); applicationContext.getBeanFactory() .registerSingleton("testMasterPasswordProvider", new TestMasterPasswordProvider()); } @Test public void testMasterPasswordChange() throws Exception { // keytool -storepasswd -new geoserver1 -storepass geoserver -storetype jceks -keystore geoserver.jks String masterPWAsString = getMasterPassword(); MasterPasswordConfig config = getSecurityManager().getMasterPasswordConfig(); URLMasterPasswordProviderConfig mpConfig = (URLMasterPasswordProviderConfig) getSecurityManager().loadMasterPassswordProviderConfig(config.getProviderName()); assertTrue(mpConfig.getURL().toString().endsWith(URLMasterPasswordProviderConfig.MASTER_PASSWD_FILENAME)); getSecurityManager().getKeyStoreProvider().reloadKeyStore(); try { getSecurityManager().saveMasterPasswordConfig(config, null, null, null); fail(); } catch (MasterPasswordChangeException ex) { } ///// First change using rw_url mpConfig = new URLMasterPasswordProviderConfig(); mpConfig.setName("rw"); mpConfig.setClassName(URLMasterPasswordProvider.class.getCanonicalName()); mpConfig.setReadOnly(false); File tmp = new File(getSecurityManager().get("security").dir(),"mpw1.properties"); mpConfig.setURL(DataUtilities.fileToURL(tmp)); getSecurityManager().saveMasterPasswordProviderConfig(mpConfig); config = getSecurityManager().getMasterPasswordConfig(); config.setProviderName(mpConfig.getName()); getSecurityManager().saveMasterPasswordConfig( config, masterPWAsString.toCharArray(), "geoserver1".toCharArray(), "geoserver1".toCharArray()); assertEquals("geoserver1", getMasterPassword()); getSecurityManager().getKeyStoreProvider().getConfigPasswordKey(); /////////////// change with ro url mpConfig = new URLMasterPasswordProviderConfig(); mpConfig.setName("ro"); mpConfig.setClassName(URLMasterPasswordProvider.class.getCanonicalName()); mpConfig.setReadOnly(true); tmp = new File(getSecurityManager().get("security").dir(),"mpw2.properties"); mpConfig.setURL(DataUtilities.fileToURL(tmp)); FileUtils.writeStringToFile(tmp, "geoserver2"); getSecurityManager().saveMasterPasswordProviderConfig(mpConfig); config = getSecurityManager().getMasterPasswordConfig(); config.setProviderName("ro"); getSecurityManager().saveMasterPasswordConfig( config, "geoserver1".toCharArray(), null, "geoserver2".toCharArray()); assertEquals("geoserver2",getMasterPassword()); getSecurityManager().getKeyStoreProvider().getConfigPasswordKey(); /////////////////////// change simulating spring injection MasterPasswordProviderConfig mpConfig2 = new MasterPasswordProviderConfig(); mpConfig2.setName("test"); mpConfig2.setClassName(TestMasterPasswordProvider.class.getCanonicalName()); getSecurityManager().saveMasterPasswordProviderConfig(mpConfig2); config =getSecurityManager().getMasterPasswordConfig(); config.setProviderName("test"); getSecurityManager().saveMasterPasswordConfig( config, "geoserver2".toCharArray(), "geoserver3".toCharArray(), "geoserver3".toCharArray()); // now, a geoserver restart should appear, simulate with getSecurityManager().getKeyStoreProvider().commitMasterPasswordChange(); ////////// assertEquals("geoserver3",getMasterPassword()); getSecurityManager().getKeyStoreProvider().getConfigPasswordKey(); /// Test root login after master password change Authentication auth = new UsernamePasswordAuthenticationToken("root", "geoserver3"); GeoServerRootAuthenticationProvider authProvider = new GeoServerRootAuthenticationProvider(); authProvider.setSecurityManager(getSecurityManager()); auth = authProvider.authenticate(auth); assertTrue(auth.isAuthenticated()); auth = new UsernamePasswordAuthenticationToken("root", "abcdefghijk"); assertNull(authProvider.authenticate(auth)); assertFalse(auth.isAuthenticated()); } }