use of org.apache.geode.cache.operations.OperationContext.OperationCode in project geode by apache.
the class ClientAuthorizationDUnitTest method testDisallowPutsGets.
@Test
public void testDisallowPutsGets() {
AuthzCredentialGenerator gen = getXmlAuthzGenerator();
CredentialGenerator cGen = gen.getCredentialGenerator();
Properties extraAuthProps = cGen.getSystemProperties();
Properties javaProps = cGen.getJavaProperties();
Properties extraAuthzProps = gen.getSystemProperties();
String authenticator = cGen.getAuthenticator();
String authInit = cGen.getAuthInit();
String accessor = gen.getAuthorizationCallback();
getLogWriter().info("testDisallowPutsGets: Using authinit: " + authInit);
getLogWriter().info("testDisallowPutsGets: Using authenticator: " + authenticator);
getLogWriter().info("testDisallowPutsGets: Using accessor: " + accessor);
// Check that we indeed can obtain valid credentials not allowed to do gets
Properties createCredentials = gen.getAllowedCredentials(new OperationCode[] { OperationCode.PUT }, new String[] { regionName }, 1);
Properties createJavaProps = cGen.getJavaProperties();
getLogWriter().info("testDisallowPutsGets: For first client credentials: " + createCredentials);
Properties getCredentials = gen.getDisallowedCredentials(new OperationCode[] { OperationCode.GET }, new String[] { regionName }, 2);
Properties getJavaProps = cGen.getJavaProperties();
getLogWriter().info("testDisallowPutsGets: For second client disallowed GET credentials: " + getCredentials);
// Start servers with all required properties
Properties serverProps = buildProperties(authenticator, accessor, false, extraAuthProps, extraAuthzProps);
int port1 = createServer1(javaProps, serverProps);
int port2 = createServer2(javaProps, serverProps);
createClient1NoException(createJavaProps, authInit, port1, port2, createCredentials);
createClient2NoException(getJavaProps, authInit, port1, port2, getCredentials);
// Perform some put operations from client1
client1.invoke(() -> doPuts(2, NO_EXCEPTION));
// Gets as normal user should throw exception
client2.invoke(() -> doGets(2, NOTAUTHZ_EXCEPTION));
// Try to connect client2 with reader credentials
getCredentials = gen.getAllowedCredentials(new OperationCode[] { OperationCode.GET }, new String[] { regionName }, 5);
getJavaProps = cGen.getJavaProperties();
getLogWriter().info("testDisallowPutsGets: For second client with GET credentials: " + getCredentials);
createClient2NoException(getJavaProps, authInit, port1, port2, getCredentials);
// Verify that the gets succeed
client2.invoke(() -> doGets(2, NO_EXCEPTION));
// Verify that the puts throw exception
client2.invoke(() -> doNPuts(2, NOTAUTHZ_EXCEPTION));
}
use of org.apache.geode.cache.operations.OperationContext.OperationCode in project geode by apache.
the class ClientAuthorizationTestCase method executeOpBlock.
protected void executeOpBlock(final List<OperationWithAction> opBlock, final int port1, final int port2, final String authInit, final Properties extraAuthProps, final Properties extraAuthzProps, final TestCredentialGenerator credentialGenerator, final Random random) throws InterruptedException {
for (Iterator<OperationWithAction> opIter = opBlock.iterator(); opIter.hasNext(); ) {
// Start client with valid credentials as specified in OperationWithAction
OperationWithAction currentOp = opIter.next();
OperationCode opCode = currentOp.getOperationCode();
int opFlags = currentOp.getFlags();
int clientNum = currentOp.getClientNum();
VM clientVM = null;
boolean useThisVM = false;
switch(clientNum) {
case 1:
clientVM = client1;
break;
case 2:
clientVM = client2;
break;
case 3:
useThisVM = true;
break;
default:
fail("executeOpBlock: Unknown client number " + clientNum);
break;
}
System.out.println("executeOpBlock: performing operation number [" + currentOp.getOpNum() + "]: " + currentOp);
if ((opFlags & OpFlags.USE_OLDCONN) == 0) {
Properties opCredentials;
int newRnd = random.nextInt(100) + 1;
String currentRegionName = '/' + regionName;
if ((opFlags & OpFlags.USE_SUBREGION) > 0) {
currentRegionName += ('/' + SUBREGION_NAME);
}
String credentialsTypeStr;
OperationCode authOpCode = currentOp.getAuthzOperationCode();
int[] indices = currentOp.getIndices();
CredentialGenerator cGen = credentialGenerator.getCredentialGenerator();
final Properties javaProps = cGen == null ? null : cGen.getJavaProperties();
if ((opFlags & OpFlags.CHECK_NOTAUTHZ) > 0 || (opFlags & OpFlags.USE_NOTAUTHZ) > 0) {
opCredentials = credentialGenerator.getDisallowedCredentials(new OperationCode[] { authOpCode }, new String[] { currentRegionName }, indices, newRnd);
credentialsTypeStr = " unauthorized " + authOpCode;
} else {
opCredentials = credentialGenerator.getAllowedCredentials(new OperationCode[] { opCode, authOpCode }, new String[] { currentRegionName }, indices, newRnd);
credentialsTypeStr = " authorized " + authOpCode;
}
Properties clientProps = concatProperties(new Properties[] { opCredentials, extraAuthProps, extraAuthzProps });
// Start the client with valid credentials but allowed or disallowed to perform an operation
System.out.println("executeOpBlock: For client" + clientNum + credentialsTypeStr + " credentials: " + opCredentials);
boolean setupDynamicRegionFactory = (opFlags & OpFlags.ENABLE_DRF) > 0;
if (useThisVM) {
SecurityTestUtils.createCacheClientWithDynamicRegion(authInit, clientProps, javaProps, 0, setupDynamicRegionFactory, NO_EXCEPTION);
} else {
clientVM.invoke("SecurityTestUtils.createCacheClientWithDynamicRegion", () -> SecurityTestUtils.createCacheClientWithDynamicRegion(authInit, clientProps, javaProps, 0, setupDynamicRegionFactory, NO_EXCEPTION));
}
}
int expectedResult;
if ((opFlags & OpFlags.CHECK_NOTAUTHZ) > 0) {
expectedResult = NOTAUTHZ_EXCEPTION;
} else if ((opFlags & OpFlags.CHECK_EXCEPTION) > 0) {
expectedResult = OTHER_EXCEPTION;
} else {
expectedResult = NO_EXCEPTION;
}
// Perform the operation from selected client
if (useThisVM) {
doOp(opCode, currentOp.getIndices(), new Integer(opFlags), new Integer(expectedResult));
} else {
int[] indices = currentOp.getIndices();
clientVM.invoke("ClientAuthorizationTestCase.doOp", () -> ClientAuthorizationTestCase.doOp(opCode, indices, new Integer(opFlags), new Integer(expectedResult)));
}
}
}
use of org.apache.geode.cache.operations.OperationContext.OperationCode in project geode by apache.
the class DeltaClientPostAuthorizationDUnitTest method executeOpBlock.
@Override
protected void executeOpBlock(final List<OperationWithAction> opBlock, final int port1, final int port2, final String authInit, final Properties extraAuthProps, final Properties extraAuthzProps, final TestCredentialGenerator credentialGenerator, final Random random) throws InterruptedException {
for (Iterator<OperationWithAction> opIter = opBlock.iterator(); opIter.hasNext(); ) {
// Start client with valid credentials as specified in OperationWithAction
OperationWithAction currentOp = opIter.next();
OperationCode opCode = currentOp.getOperationCode();
int opFlags = currentOp.getFlags();
int clientNum = currentOp.getClientNum();
VM clientVM = null;
boolean useThisVM = false;
switch(clientNum) {
case 1:
clientVM = client1;
break;
case 2:
clientVM = client2;
break;
case 3:
useThisVM = true;
break;
default:
fail("executeOpBlock: Unknown client number " + clientNum);
break;
}
getLogWriter().info("executeOpBlock: performing operation number [" + currentOp.getOpNum() + "]: " + currentOp);
if ((opFlags & OpFlags.USE_OLDCONN) == 0) {
Properties opCredentials;
int newRnd = random.nextInt(100) + 1;
String currentRegionName = '/' + regionName;
if ((opFlags & OpFlags.USE_SUBREGION) > 0) {
currentRegionName += ('/' + SUBREGION_NAME);
}
String credentialsTypeStr;
OperationCode authOpCode = currentOp.getAuthzOperationCode();
int[] indices = currentOp.getIndices();
CredentialGenerator cGen = credentialGenerator.getCredentialGenerator();
final Properties javaProps = cGen == null ? null : cGen.getJavaProperties();
if ((opFlags & OpFlags.CHECK_NOTAUTHZ) > 0 || (opFlags & OpFlags.USE_NOTAUTHZ) > 0) {
opCredentials = credentialGenerator.getDisallowedCredentials(new OperationCode[] { authOpCode }, new String[] { currentRegionName }, indices, newRnd);
credentialsTypeStr = " unauthorized " + authOpCode;
} else {
opCredentials = credentialGenerator.getAllowedCredentials(new OperationCode[] { opCode, authOpCode }, new String[] { currentRegionName }, indices, newRnd);
credentialsTypeStr = " authorized " + authOpCode;
}
Properties clientProps = concatProperties(new Properties[] { opCredentials, extraAuthProps, extraAuthzProps });
// Start the client with valid credentials but allowed or disallowed to perform an operation
getLogWriter().info("executeOpBlock: For client" + clientNum + credentialsTypeStr + " credentials: " + opCredentials);
boolean setupDynamicRegionFactory = (opFlags & OpFlags.ENABLE_DRF) > 0;
if (useThisVM) {
createCacheClient(authInit, clientProps, javaProps, new int[] { port1, port2 }, 0, setupDynamicRegionFactory, NO_EXCEPTION);
} else {
clientVM.invoke(() -> createCacheClient(authInit, clientProps, javaProps, new int[] { port1, port2 }, 0, setupDynamicRegionFactory, NO_EXCEPTION));
}
}
int expectedResult;
if ((opFlags & OpFlags.CHECK_NOTAUTHZ) > 0) {
expectedResult = NOTAUTHZ_EXCEPTION;
} else if ((opFlags & OpFlags.CHECK_EXCEPTION) > 0) {
expectedResult = OTHER_EXCEPTION;
} else {
expectedResult = NO_EXCEPTION;
}
// Perform the operation from selected client
if (useThisVM) {
doOp(opCode, currentOp.getIndices(), new Integer(opFlags), new Integer(expectedResult));
} else {
int[] indices = currentOp.getIndices();
clientVM.invoke(() -> DeltaClientPostAuthorizationDUnitTest.doOp(opCode, indices, new Integer(opFlags), new Integer(expectedResult)));
}
}
}
use of org.apache.geode.cache.operations.OperationContext.OperationCode in project geode by apache.
the class XmlAuthorization method authorizeOperation.
/**
* Return true if the given operation is allowed for the cache/region.
*
* This looks up the cached permissions of the principal in the map for the provided region name.
* If none are found then the global permissions with empty region name are looked up. The
* operation is allowed if it is found this permission list.
*
* @param regionName When null then it indicates a cache-level operation, else the name of the
* region for the operation.
* @param context the data required by the operation
*
* @return true if the operation is authorized and false otherwise
*/
@Override
public boolean authorizeOperation(String regionName, final OperationContext context) {
Map<OperationCode, FunctionSecurityPrmsHolder> operationMap;
// Check GET permissions for updates from server to client
if (context.isClientUpdate()) {
operationMap = this.allowedOps.get(regionName);
if (operationMap == null && regionName.length() > 0) {
operationMap = this.allowedOps.get(EMPTY_VALUE);
}
if (operationMap != null) {
return operationMap.containsKey(OperationCode.GET);
}
return false;
}
OperationCode opCode = context.getOperationCode();
if (opCode.isQuery() || opCode.isExecuteCQ() || opCode.isCloseCQ() || opCode.isStopCQ()) {
// First check if cache-level permission has been provided
operationMap = this.allowedOps.get(EMPTY_VALUE);
boolean globalPermission = (operationMap != null && operationMap.containsKey(opCode));
Set<String> regionNames = ((QueryOperationContext) context).getRegionNames();
if (regionNames == null || regionNames.size() == 0) {
return globalPermission;
}
for (String r : regionNames) {
regionName = normalizeRegionName(r);
operationMap = this.allowedOps.get(regionName);
if (operationMap == null) {
if (!globalPermission) {
return false;
}
} else if (!operationMap.containsKey(opCode)) {
return false;
}
}
return true;
}
final String normalizedRegionName = normalizeRegionName(regionName);
operationMap = this.allowedOps.get(normalizedRegionName);
if (operationMap == null && normalizedRegionName.length() > 0) {
operationMap = this.allowedOps.get(EMPTY_VALUE);
}
if (operationMap != null) {
if (context.getOperationCode() != OperationCode.EXECUTE_FUNCTION) {
return operationMap.containsKey(context.getOperationCode());
} else {
if (!operationMap.containsKey(context.getOperationCode())) {
return false;
} else {
if (!context.isPostOperation()) {
FunctionSecurityPrmsHolder functionParameter = operationMap.get(context.getOperationCode());
ExecuteFunctionOperationContext functionContext = (ExecuteFunctionOperationContext) context;
// OnRegion execution
if (functionContext.getRegionName() != null) {
if (functionParameter.isOptimizeForWrite() != null && functionParameter.isOptimizeForWrite().booleanValue() != functionContext.isOptimizeForWrite()) {
return false;
}
if (functionParameter.getFunctionIds() != null && !functionParameter.getFunctionIds().contains(functionContext.getFunctionId())) {
return false;
}
if (functionParameter.getKeySet() != null && functionContext.getKeySet() != null) {
if (functionContext.getKeySet().containsAll(functionParameter.getKeySet())) {
return false;
}
}
return true;
} else {
// On Server execution
if (functionParameter.getFunctionIds() != null && !functionParameter.getFunctionIds().contains(functionContext.getFunctionId())) {
return false;
}
return true;
}
} else {
ExecuteFunctionOperationContext functionContext = (ExecuteFunctionOperationContext) context;
FunctionSecurityPrmsHolder functionParameter = operationMap.get(context.getOperationCode());
if (functionContext.getRegionName() != null) {
if (functionContext.getResult() instanceof ArrayList && functionParameter.getKeySet() != null) {
ArrayList<String> resultList = (ArrayList) functionContext.getResult();
Set<String> nonAllowedKeys = functionParameter.getKeySet();
if (resultList.containsAll(nonAllowedKeys)) {
return false;
}
}
return true;
} else {
ArrayList<String> resultList = (ArrayList) functionContext.getResult();
final String inSecureItem = "Insecure item";
if (resultList.contains(inSecureItem)) {
return false;
}
return true;
}
}
}
}
}
return false;
}
use of org.apache.geode.cache.operations.OperationContext.OperationCode in project geode by apache.
the class XmlAuthorization method init.
/**
* Cache authorization information for all users statically. This method is not thread-safe and is
* should either be invoked only once, or the caller should take the appropriate locks.
*
* @param cache reference to the cache object for the distributed system
*/
private static void init(final Cache cache) throws NotAuthorizedException {
final LogWriter systemLogWriter = cache.getLogger();
final String xmlDocumentUri = (String) cache.getDistributedSystem().getSecurityProperties().get(DOC_URI_PROP_NAME);
try {
if (xmlDocumentUri == null) {
throw new NotAuthorizedException("No ACL file defined using tag [" + DOC_URI_PROP_NAME + "] in system properties");
}
if (xmlDocumentUri.equals(XmlAuthorization.currentDocUri)) {
if (XmlAuthorization.xmlLoadFailure != null) {
throw XmlAuthorization.xmlLoadFailure;
}
return;
}
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setValidating(true);
final DocumentBuilder builder = factory.newDocumentBuilder();
final XmlErrorHandler errorHandler = new XmlErrorHandler(systemLogWriter, xmlDocumentUri);
builder.setErrorHandler(errorHandler);
builder.setEntityResolver(new AuthzDtdResolver());
final Document xmlDocument = builder.parse(xmlDocumentUri);
XmlAuthorization.userRoles = new HashMap<String, HashSet<String>>();
XmlAuthorization.rolePermissions = new HashMap<String, Map<String, Map<OperationCode, FunctionSecurityPrmsHolder>>>();
final NodeList roleUserNodes = xmlDocument.getElementsByTagName(TAG_ROLE);
for (int roleIndex = 0; roleIndex < roleUserNodes.getLength(); roleIndex++) {
final Node roleUserNode = roleUserNodes.item(roleIndex);
final String roleName = getAttributeValue(roleUserNode, ATTR_ROLENAME);
final NodeList userNodes = roleUserNode.getChildNodes();
for (int userIndex = 0; userIndex < userNodes.getLength(); userIndex++) {
final Node userNode = userNodes.item(userIndex);
if (TAG_USER.equals(userNode.getNodeName())) {
final String userName = getNodeValue(userNode);
HashSet<String> userRoleSet = XmlAuthorization.userRoles.get(userName);
if (userRoleSet == null) {
userRoleSet = new HashSet<String>();
XmlAuthorization.userRoles.put(userName, userRoleSet);
}
userRoleSet.add(roleName);
} else {
throw new SAXParseException("Unknown tag [" + userNode.getNodeName() + "] as child of tag [" + TAG_ROLE + ']', null);
}
}
}
final NodeList rolePermissionNodes = xmlDocument.getElementsByTagName(TAG_PERMS);
for (int permIndex = 0; permIndex < rolePermissionNodes.getLength(); permIndex++) {
final Node rolePermissionNode = rolePermissionNodes.item(permIndex);
final String roleName = getAttributeValue(rolePermissionNode, ATTR_ROLE);
Map<String, Map<OperationCode, FunctionSecurityPrmsHolder>> regionOperationMap = XmlAuthorization.rolePermissions.get(roleName);
if (regionOperationMap == null) {
regionOperationMap = new HashMap<String, Map<OperationCode, FunctionSecurityPrmsHolder>>();
XmlAuthorization.rolePermissions.put(roleName, regionOperationMap);
}
final NodeList operationNodes = rolePermissionNode.getChildNodes();
final HashMap<OperationCode, FunctionSecurityPrmsHolder> operationMap = new HashMap<OperationCode, FunctionSecurityPrmsHolder>();
for (int opIndex = 0; opIndex < operationNodes.getLength(); opIndex++) {
final Node operationNode = operationNodes.item(opIndex);
if (TAG_OP.equals(operationNode.getNodeName())) {
final String operationName = getNodeValue(operationNode);
final OperationCode code = OperationCode.valueOf(operationName);
if (code == null) {
throw new SAXParseException("Unknown operation [" + operationName + ']', null);
}
if (code != OperationCode.EXECUTE_FUNCTION) {
operationMap.put(code, null);
} else {
final String optimizeForWrite = getAttributeValue(operationNode, ATTR_FUNCTION_OPTIMIZE_FOR_WRITE);
final String functionAttr = getAttributeValue(operationNode, ATTR_FUNCTION_IDS);
final String keysAttr = getAttributeValue(operationNode, ATTR_FUNCTION_KEY_SET);
Boolean isOptimizeForWrite;
HashSet<String> functionIds;
HashSet<String> keySet;
if (optimizeForWrite == null || optimizeForWrite.length() == 0) {
isOptimizeForWrite = null;
} else {
isOptimizeForWrite = Boolean.parseBoolean(optimizeForWrite);
}
if (functionAttr == null || functionAttr.length() == 0) {
functionIds = null;
} else {
final String[] functionArray = functionAttr.split(",");
functionIds = new HashSet<String>();
for (int strIndex = 0; strIndex < functionArray.length; ++strIndex) {
functionIds.add((functionArray[strIndex]));
}
}
if (keysAttr == null || keysAttr.length() == 0) {
keySet = null;
} else {
final String[] keySetArray = keysAttr.split(",");
keySet = new HashSet<String>();
for (int strIndex = 0; strIndex < keySetArray.length; ++strIndex) {
keySet.add((keySetArray[strIndex]));
}
}
final FunctionSecurityPrmsHolder functionContext = new FunctionSecurityPrmsHolder(isOptimizeForWrite, functionIds, keySet);
operationMap.put(code, functionContext);
}
} else {
throw new SAXParseException("Unknown tag [" + operationNode.getNodeName() + "] as child of tag [" + TAG_PERMS + ']', null);
}
}
final String regionNames = getAttributeValue(rolePermissionNode, ATTR_REGIONS);
if (regionNames == null || regionNames.length() == 0) {
regionOperationMap.put(EMPTY_VALUE, operationMap);
} else {
final String[] regionNamesSplit = regionNames.split(",");
for (int strIndex = 0; strIndex < regionNamesSplit.length; ++strIndex) {
regionOperationMap.put(normalizeRegionName(regionNamesSplit[strIndex]), operationMap);
}
}
}
XmlAuthorization.currentDocUri = xmlDocumentUri;
} catch (Exception ex) {
String message;
if (ex instanceof NotAuthorizedException) {
message = ex.getMessage();
} else {
message = ex.getClass().getName() + ": " + ex.getMessage();
}
systemLogWriter.warning("XmlAuthorization.init: " + message);
XmlAuthorization.xmlLoadFailure = new NotAuthorizedException(message, ex);
throw XmlAuthorization.xmlLoadFailure;
}
}
Aggregations