/* * 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.internal.security; import java.security.Principal; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.geode.DataSerializable; import org.apache.geode.DataSerializer; import org.apache.geode.Instantiator; import org.apache.geode.cache.Cache; import org.apache.geode.cache.operations.PutAllOperationContext; import org.apache.geode.cache.operations.PutOperationContext; import org.apache.geode.cache.operations.OperationContext; import org.apache.geode.cache.operations.OperationContext.OperationCode; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.i18n.LogWriterI18n; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.HeapDataOutputStream; import org.apache.geode.internal.Version; import org.apache.geode.internal.cache.CachedDeserializable; import org.apache.geode.internal.cache.CachedDeserializableFactory; import org.apache.geode.security.AccessControl; import org.apache.geode.security.NotAuthorizedException; /** * An authorization implementation for testing that changes a string value in pre-operation phase to * add an integer denoting which <code>Principal</code>s would be allowed to get that object. * * @since GemFire 5.5 */ public class FilterPreAuthorization implements AccessControl { private LogWriterI18n logger; static { Instantiator.register(new Instantiator(ObjectWithAuthz.class, ObjectWithAuthz.CLASSID) { @Override public DataSerializable newInstance() { return new ObjectWithAuthz(); } }, false); } public FilterPreAuthorization() { this.logger = null; } public static AccessControl create() { return new FilterPreAuthorization(); } public void init(Principal principal, DistributedMember remoteMember, Cache cache) throws NotAuthorizedException { this.logger = cache.getSecurityLoggerI18n(); } public boolean authorizeOperation(String regionName, OperationContext context) { assert !context.isPostOperation(); OperationCode opCode = context.getOperationCode(); if (opCode.isPut()) { PutOperationContext createContext = (PutOperationContext) context; // byte[] serializedValue = createContext.getSerializedValue(); byte[] serializedValue = null; Object value = createContext.getValue(); int valLength; byte lastByte; if (value == null) { // This means serializedValue too is null. valLength = 0; lastByte = 0; } else { if (value instanceof byte[]) { serializedValue = (byte[]) value; valLength = serializedValue.length; lastByte = serializedValue[valLength - 1]; } else { ObjectWithAuthz authzObj = new ObjectWithAuthz(value, Integer.valueOf(value.hashCode())); createContext.setValue(authzObj, true); return true; } } HeapDataOutputStream hos = new HeapDataOutputStream(valLength + 32, Version.CURRENT); try { InternalDataSerializer.writeUserDataSerializableHeader(ObjectWithAuthz.CLASSID, hos); if (serializedValue != null) { hos.write(serializedValue); } // Some value that determines the Principals that can get this object. Integer allowedIndex = Integer.valueOf(lastByte); DataSerializer.writeObject(allowedIndex, hos); } catch (Exception ex) { return false; } createContext.setSerializedValue(hos.toByteArray(), true); if (this.logger.fineEnabled()) this.logger.fine("FilterPreAuthorization: added authorization " + "info for key: " + createContext.getKey()); } else if (opCode.isPutAll()) { PutAllOperationContext createContext = (PutAllOperationContext) context; Map map = createContext.getMap(); Collection entries = map.entrySet(); Iterator iterator = entries.iterator(); Map.Entry mapEntry = null; while (iterator.hasNext()) { mapEntry = (Map.Entry) iterator.next(); String currkey = (String) mapEntry.getKey(); Object value = mapEntry.getValue(); Integer authCode; if (value != null) { String valStr = value.toString(); authCode = (int) valStr.charAt(valStr.length() - 1); } else { authCode = 0; } ObjectWithAuthz authzObj = new ObjectWithAuthz(value, authCode); mapEntry.setValue(authzObj); if (this.logger.fineEnabled()) this.logger.fine( "FilterPreAuthorization: putAll: added authorization " + "info for key: " + currkey); } // Now each of the map's values have become ObjectWithAuthz } return true; } public void close() {} }