blob: 1243f16e6581085e1ec73cf1bfda73d7dcb59810 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.security;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.client.Pool;
import org.apache.geode.cache.execute.FunctionService;
import org.apache.geode.cache.query.CqAttributesFactory;
import org.apache.geode.cache.query.CqException;
import org.apache.geode.cache.query.CqQuery;
import org.apache.geode.cache.query.Query;
import org.apache.geode.distributed.ConfigurationProperties;
import org.apache.geode.internal.cache.GemFireCacheImpl;
import org.apache.geode.internal.cache.PoolManagerImpl;
import org.apache.geode.security.generator.CredentialGenerator;
import org.apache.geode.security.generator.DummyCredentialGenerator;
import org.apache.geode.test.junit.categories.DistributedTest;
import org.apache.geode.test.junit.categories.SecurityTest;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.util.Properties;
import static org.apache.geode.security.SecurityTestUtils.NO_EXCEPTION;
import static org.apache.geode.test.dunit.Assert.fail;
import static org.apache.geode.test.dunit.LogWriterUtils.getLogWriter;
@Category({DistributedTest.class, SecurityTest.class})
public class MultiUserAPIDUnitTest extends ClientAuthorizationTestCase {
private static final String[] serverIgnoredExceptions =
{AuthenticationRequiredException.class.getName(),
AuthenticationFailedException.class.getName(), GemFireSecurityException.class.getName(),
ClassNotFoundException.class.getName(), IOException.class.getName(),
SSLException.class.getName(), SSLHandshakeException.class.getName()};
private static final String[] clientIgnoredExceptions =
{AuthenticationRequiredException.class.getName(),
AuthenticationFailedException.class.getName(), SSLHandshakeException.class.getName()};
@Test
public void testSingleUserUnsupportedAPIs() {
// Start servers
// Start clients with multiuser-authentication set to false
setUpVMs(new DummyCredentialGenerator(), false);
client1.invoke(() -> verifyDisallowedOps(false));
}
@Test
public void testMultiUserUnsupportedAPIs() {
// Start servers.
// Start clients with multiuser-authentication set to true.
setUpVMs(new DummyCredentialGenerator(), true);
client1.invoke(() -> verifyDisallowedOps(true));
}
private void verifyDisallowedOps(final boolean multiUserMode) throws Exception {
String op = "unknown";
boolean success = false;
if (!multiUserMode) {
success = false;
try {
// Attempt cache.createAuthenticatedCacheView() and expect an exception, fail otherwise
op = "Pool.createSecureUserCache()";
GemFireCacheImpl.getInstance().createAuthenticatedView(new Properties(), "testPool");
} catch (IllegalStateException uoe) {
getLogWriter().info(op + ": Got expected exception: " + uoe);
success = true;
}
if (!success) {
fail("Did not get exception while doing " + op);
}
} else { // multiuser mode
Region realRegion = GemFireCacheImpl.getInstance().getRegion(SecurityTestUtils.REGION_NAME);
Region proxyRegion =
SecurityTestUtils.getProxyCaches(0).getRegion(SecurityTestUtils.REGION_NAME);
Pool pool = PoolManagerImpl.getPMI().find("testPool");
for (int i = 0; i <= 27; i++) {
success = false;
try {
switch (i) {
// Attempt (real) Region.create/put/get/containsKeyOnServer/destroy/
// destroyRegion/clear/remove/registerInterest/unregisterInterest()
// and expect an exception, fail otherwise.
case 0:
op = "Region.create()";
realRegion.create("key", "value");
break;
case 1:
op = "Region.put()";
realRegion.put("key", "value");
break;
case 2:
op = "Region.get()";
realRegion.get("key");
break;
case 3:
op = "Region.containsKeyOnServer()";
realRegion.containsKeyOnServer("key");
break;
case 4:
op = "Region.remove()";
realRegion.remove("key");
break;
case 5:
op = "Region.destroy()";
realRegion.destroy("key");
break;
case 6:
op = "Region.destroyRegion()";
realRegion.destroyRegion();
break;
case 7:
op = "Region.registerInterest()";
realRegion.registerInterest("key");
break;
// case 8:
// op = "Region.unregisterInterest()";
// realRegion.unregisterInterest("key");
// break;
case 8:
op = "Region.clear()";
realRegion.clear();
break;
// Attempt ProxyRegion.createSubregion/forceRolling/
// getAttributesMutator/registerInterest/loadSnapShot/saveSnapshot/
// setUserAttribute/unregisterInterest/writeToDisk
// and expect an exception, fail otherwise.
case 9:
op = "ProxyRegion.createSubregion()";
proxyRegion.createSubregion("subregion", null);
break;
case 10:
op = "ProxyRegion.forceRolling()";
proxyRegion.forceRolling();
break;
case 11:
op = "ProxyRegion.getAttributesMutator()";
proxyRegion.getAttributesMutator();
break;
case 12:
op = "ProxyRegion.registerInterest()";
proxyRegion.registerInterest("key");
break;
case 13:
op = "ProxyRegion.loadSnapshot()";
proxyRegion.loadSnapshot(null);
break;
case 14:
op = "ProxyRegion.saveSnapshot()";
proxyRegion.saveSnapshot(null);
break;
case 15:
op = "ProxyRegion.setUserAttribute()";
proxyRegion.setUserAttribute(null);
break;
case 16:
op = "ProxyRegion.unregisterInterestRegex()";
proxyRegion.unregisterInterestRegex("*");
break;
// Attempt FunctionService.onRegion/onServer/s(pool) and expect an
// exception, fail otherwise.
case 17:
op = "FunctionService.onRegion()";
FunctionService.onRegion(realRegion);
break;
case 18:
op = "FunctionService.onServer(pool)";
FunctionService.onServer(pool);
break;
case 19:
op = "FunctionService.onServers(pool)";
FunctionService.onServers(pool);
break;
// Attempt
// QueryService.newQuery().execute()/newCq().execute/executeWithInitialResults()
case 20:
op = "QueryService.newQuery.execute()";
Query query = pool.getQueryService()
.newQuery("SELECT * FROM /" + SecurityTestUtils.REGION_NAME);
query.execute();
break;
case 21:
op = "QueryService.newCq.execute()";
CqQuery cqQuery =
pool.getQueryService().newCq("SELECT * FROM /" + SecurityTestUtils.REGION_NAME,
new CqAttributesFactory().create());
try {
cqQuery.execute();
} catch (CqException ce) {
throw (Exception) ce.getCause();
}
break;
case 22:
op = "QueryService.newCq.executeWithInitialResults()";
cqQuery =
pool.getQueryService().newCq("SELECT * FROM /" + SecurityTestUtils.REGION_NAME,
new CqAttributesFactory().create());
try {
cqQuery.executeWithInitialResults();
} catch (CqException ce) {
throw (Exception) ce.getCause();
}
break;
// Attempt ProxyQueryService.getIndex/createIndex/removeIndex() and
// expect an exception, fail otherwise.
case 23:
op = "ProxyQueryService().getIndexes()";
SecurityTestUtils.getProxyCaches(0).getQueryService().getIndexes(null);
break;
case 24:
op = "ProxyQueryService().createIndex()";
SecurityTestUtils.getProxyCaches(0).getQueryService().createIndex(null, null, null);
break;
case 25:
op = "ProxyQueryService().removeIndexes()";
SecurityTestUtils.getProxyCaches(0).getQueryService().removeIndexes();
break;
case 26:
op = "ProxyRegion.localDestroy()";
proxyRegion.localDestroy("key");
break;
case 27:
op = "ProxyRegion.localInvalidate()";
proxyRegion.localInvalidate("key");
break;
default:
fail("Unknown op code: " + i);
break;
}
} catch (UnsupportedOperationException uoe) {
getLogWriter().info(op + ": Got expected exception: " + uoe);
success = true;
}
if (!success) {
fail("Did not get exception while doing " + op);
}
}
}
}
private void setUpVMs(final CredentialGenerator gen, final boolean multiUser) {
Properties extraProps = gen.getSystemProperties();
Properties javaProps = gen.getJavaProperties();
String authenticator = gen.getAuthenticator();
String authInit = gen.getAuthInit();
getLogWriter().info("testValidCredentials: Using scheme: " + gen.classCode());
getLogWriter().info("testValidCredentials: Using authenticator: " + authenticator);
getLogWriter().info("testValidCredentials: Using authinit: " + authInit);
// Start the servers
int locPort1 = SecurityTestUtils.getLocatorPort();
int locPort2 = SecurityTestUtils.getLocatorPort();
String locString = SecurityTestUtils.getAndClearLocatorString();
int port1 = server1
.invoke(() -> createCacheServer(locPort1, locString, authenticator, extraProps, javaProps));
int port2 = server2
.invoke(() -> createCacheServer(locPort2, locString, authenticator, extraProps, javaProps));
// Start the clients with valid credentials
Properties credentials1 = gen.getValidCredentials(1);
Properties javaProps1 = gen.getJavaProperties();
getLogWriter().info(
"testValidCredentials: For first client credentials: " + credentials1 + " : " + javaProps1);
Properties credentials2 = gen.getValidCredentials(2);
Properties javaProps2 = gen.getJavaProperties();
getLogWriter().info("testValidCredentials: For second client credentials: " + credentials2
+ " : " + javaProps2);
client1.invoke(() -> createCacheClient(authInit, credentials1, javaProps1, port1, port2, 0,
multiUser, NO_EXCEPTION));
}
private int createCacheServer(final int dsPort, final String locatorString,
final String authenticator, final Properties extraProps, final Properties javaProps) {
Properties authProps = new Properties();
if (extraProps != null) {
authProps.putAll(extraProps);
}
if (authenticator != null) {
authProps.setProperty(ConfigurationProperties.SECURITY_CLIENT_AUTHENTICATOR, authenticator);
}
return SecurityTestUtils.createCacheServer(authProps, javaProps, dsPort, locatorString, 0,
NO_EXCEPTION);
}
// a
protected static void createCacheClient(final String authInit, final Properties authProps,
final Properties javaProps, final int[] ports, final int numConnections,
final boolean multiUserMode, final int expectedResult) {
SecurityTestUtils.createCacheClient(authInit, authProps, javaProps, ports, numConnections,
multiUserMode, expectedResult); // invokes SecurityTestUtils 2
}
// b
private void createCacheClient(final String authInit, final Properties authProps,
final Properties javaProps, final int port1, final int port2, final int numConnections,
final boolean multiUserMode, final int expectedResult) {
createCacheClient(authInit, authProps, javaProps, new int[] {port1, port2}, numConnections,
multiUserMode, expectedResult); // invokes a
}
}