// --- BEGIN COPYRIGHT BLOCK --- // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.policy; import java.util.*; import java.text.*; import com.netscape.certsrv.request.IRequest; import com.netscape.certsrv.request.IPolicy; import com.netscape.certsrv.request.PolicyResult; import com.netscape.certsrv.apps.*; import com.netscape.certsrv.policy.*; import com.netscape.certsrv.authority.*; import com.netscape.certsrv.common.*; import com.netscape.certsrv.logging.*; import com.netscape.certsrv.base.*; import com.netscape.cmscore.base.*; import com.netscape.certsrv.base.IConfigStore; import com.netscape.cmscore.util.*; import com.netscape.cmscore.request.ARequestQueue; /** * This is a Generic policy processor. The three main functions of * this class are: * 1. To initialize policies by reading policy configuration from the * config file, and maintain 5 sets of policies - viz Enrollment, * Renewal, Revocation and KeyRecovery and KeyArchival. * 2. To apply the configured policies on the given request. * 3. To enable policy listing/configuration via MCC console. * * Since the policy processor also implements the IPolicy interface * the processor itself presents itself as one big policy to the * request processor. * * @author kanda * @version $Revision: 14561 $, $Date: 2007-05-01 10:28:56 -0700 (Tue, 01 May 2007) $ */ public class GenericPolicyProcessor implements IPolicyProcessor { protected IConfigStore mConfig = null; protected IConfigStore mGlobalStore = null; protected IAuthority mAuthority = null; // Default System Policies public final static String[] DEF_POLICIES = {"com.netscape.cms.policy.constraints.ManualAuthentication"}; // Policies that can't be deleted nor disabled. public final static Hashtable DEF_UNDELETABLE_POLICIES = new Hashtable(); private String mId = "Policy"; private Vector mPolicyOrder = new Vector(); private Hashtable mImplTable = new Hashtable(); private Hashtable mInstanceTable = new Hashtable(); PolicySet mEnrollmentRules = new PolicySet("EnrollmentRules"); PolicySet mRenewalRules = new PolicySet("RenewalRules"); PolicySet mRevocationRules = new PolicySet("RevocationRules"); PolicySet mKeyRecoveryRules = new PolicySet("KeyRecoveryRules"); PolicySet mKeyArchivalRules = new PolicySet("KeyArchivalRules"); private String[] mSystemDefaults = null; private boolean mInitSystemPolicies; // A Table of persistent policies and their predicates. // The predicates cannot be changed during configuration. private Hashtable mUndeletablePolicies = null; public GenericPolicyProcessor() { mInitSystemPolicies = true; // CA & RA } public GenericPolicyProcessor(boolean initSystemPolicies) { mInitSystemPolicies = initSystemPolicies; // KRA } public void setId(String id) throws EBaseException { mId = id; } public String getId() { return mId; } public void startup() throws EBaseException { } /** * Shuts down this subsystem. *
*/ public void shutdown() { } public ISubsystem getAuthority() { return mAuthority; } /** * Returns the configuration store. *
* * @return configuration store */ public IConfigStore getConfigStore() { return mConfig; } /** * Initializes the PolicyProcessor *
*
* @param owner owner of this subsystem
* @param config configuration of this subsystem
* @exception EBaseException failed to initialize this Subsystem.
*/
public synchronized void init(ISubsystem owner, IConfigStore config)
throws EBaseException {
// Debug.trace("GenericPolicyProcessor::init");
mAuthority = (IAuthority) owner;
mConfig = config;
mGlobalStore =
SubsystemRegistry.getInstance().get("MAIN").getConfigStore();
// Initialize default policies system that would be
// present in the system always.
if (mInitSystemPolicies) {
initSystemPolicies(mConfig);
}
// Read listing of undeletable policies if any.
initUndeletablePolicies(mConfig);
// Read all registered policies first..
IConfigStore c;
c = config.getSubStore(PROP_IMPL);
Enumeration mImpls = c.getSubStoreNames();
while (mImpls.hasMoreElements()) {
String id = (String) mImpls.nextElement();
// The implementation id should be unique
if (mImplTable.containsKey(id))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_DUPLICATE_IMPL_ID", id));
String clPath = c.getString(id + "." + PROP_CLASS);
// We should n't let the CatchAll policies to be configurable.
if (isSystemDefaultPolicy(clPath))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_SYSTEM_POLICY_CONFIG_ERROR", clPath));
// Verify if the class is a valid implementation of
// IPolicyRule
try {
Object o = Class.forName(clPath).newInstance();
if (!(o instanceof IEnrollmentPolicy) &&
!(o instanceof IRenewalPolicy) &&
!(o instanceof IRevocationPolicy) &&
!(o instanceof IKeyRecoveryPolicy) &&
!(o instanceof IKeyArchivalPolicy))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL", clPath));
} catch (EBaseException e) {
throw e;
} catch (Exception e) {
Debug.printStackTrace(e);
throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL",
id));
}
// Register the implementation.
RegisteredPolicy regPolicy =
new RegisteredPolicy(id, clPath);
mImplTable.put(id, regPolicy);
}
// Now read the priority ordering of rule configurations.
String policyOrder = config.getString(PROP_ORDER, null);
if (policyOrder == null) {
return;
// throw new EPolicyException(PolicyResources.NO_POLICY_ORDERING);
} else {
StringTokenizer tokens = new StringTokenizer(policyOrder, ",");
while (tokens.hasMoreTokens()) {
mPolicyOrder.addElement(tokens.nextToken().trim());
}
}
// Now Read Policy configurations and construct policy objects
int numPolicies = mPolicyOrder.size();
IConfigStore ruleStore = config.getSubStore(PROP_RULE);
for (int i = 0; i < numPolicies; i++) {
String instanceName = (String) mPolicyOrder.elementAt(i);
// The instance id should be unique
if (mInstanceTable.containsKey(instanceName))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_DUPLICATE_INST_ID", instanceName));
c = ruleStore.getSubStore(instanceName);
if (c == null || c.size() == 0)
throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_CONFIG",
instanceName));
IPolicyRule rule = null;
String implName;
boolean enabled;
IExpression filterExp;
// If the policy rule is not enabled, skip it.
String enabledStr = c.getString(PROP_ENABLE, null);
if (enabledStr == null || enabledStr.trim().length() == 0 ||
enabledStr.trim().equalsIgnoreCase("true"))
enabled = true;
else
enabled = false;
implName = c.getString(PROP_IMPL_NAME, null);
if (implName == null) {
throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_CONFIG",
instanceName));
}
// Make an instance of the specified policy.
RegisteredPolicy regPolicy =
(RegisteredPolicy) mImplTable.get(implName);
if (regPolicy == null) {
String[] params = {implName, instanceName};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_IMPL_NOT_FOUND", params));
}
String classpath = regPolicy.getClassPath();
try {
rule = (IPolicyRule)
Class.forName(classpath).newInstance();
if (rule instanceof IPolicyRule)
((IPolicyRule) rule).setInstanceName(instanceName);
rule.init(this, c);
} catch (Throwable e) {
mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_POLICY_INIT_FAILED", instanceName, e.toString()));
// disable rule initialized if there is
// configuration error
enabled = false;
c.putString(PROP_ENABLE, "false");
}
if (rule == null)
continue;
// Read the predicate expression if any associated
// with the rule
String exp = c.getString(GenericPolicyProcessor.PROP_PREDICATE, null);
if (exp != null)
exp = exp.trim();
if (exp != null && exp.length() > 0) {
filterExp = PolicyPredicateParser.parse(exp);
rule.setPredicate(filterExp);
}
// Add the rule to the instance table
mInstanceTable.put(instanceName,
new PolicyInstance(instanceName, implName, rule, enabled));
if (!enabled)
continue;
// Add the rule to the policy set according to category if a
// rule is enabled.
addRule(instanceName, rule);
}
// Verify that the default policies are present and enabled.
verifyDefaultPolicyConfig();
// printPolicies();
}
public boolean isProfileRequest(IRequest request) {
String profileId = request.getExtDataInString("profileId");
if (profileId == null || profileId.equals(""))
return false;
else
return true;
}
/**
* Apply policies on the given request.
*
* @param IRequest The given request
* @return The policy result object.
*/
public PolicyResult apply(IRequest req) {
IPolicySet rules = null;
String op = (String) req.getRequestType();
if (op == null) {
// throw new AssertionException("Missing operation type in request. Can't happen!");
// Return ACCEPTED for now. Looks like even get CA chain
// is being passed in here with request type set elsewhere
// on the request.
return PolicyResult.ACCEPTED;
}
if (isProfileRequest(req)) {
Debug.trace("GenericPolicyProcessor: Profile-base Request " +
req.getRequestId().toString());
return PolicyResult.ACCEPTED;
}
if (op.equalsIgnoreCase(IRequest.ENROLLMENT_REQUEST))
rules = mEnrollmentRules;
else if (op.equalsIgnoreCase(IRequest.RENEWAL_REQUEST))
rules = mRenewalRules;
else if (op.equalsIgnoreCase(IRequest.REVOCATION_REQUEST))
rules = mRevocationRules;
else if (op.equalsIgnoreCase(IRequest.KEY_RECOVERY_REQUEST))
rules = mKeyRecoveryRules;
else if (op.equalsIgnoreCase(IRequest.KEY_ARCHIVAL_REQUEST))
rules = mKeyArchivalRules;
else {
// It aint' a CMP request. We don't care.
return PolicyResult.ACCEPTED;
// throw new AssertionException("Invalid request type. Can't Happen!");
}
// ((PolicySet)rules).printPolicies();
// If there are no rules, then it is a serious error.
if (rules.count() == 0) {
// if no policy is specified, just accept the request.
// KRA has no policy configured by default
return PolicyResult.ACCEPTED;
/**
setError(req, PolicyResources.NO_RULES_CONFIGURED, op);
return PolicyResult.REJECTED;
**/
}
// request must be up to date or can't process it.
PolicyResult res = PolicyResult.ACCEPTED;
String mVersion = ARequestQueue.REQUEST_VERSION;
String vers = req.getRequestVersion();
if (vers == null || !vers.equals(mVersion)) {
if (vers == null || vers.length() == 0)
vers = "none";
res = PolicyResult.REJECTED;
}
if (res == PolicyResult.REJECTED)
return res;
// Apply the policy rules.
return rules.apply(req);
}
public void printPolicies() {
mEnrollmentRules.printPolicies();
mRenewalRules.printPolicies();
mRevocationRules.printPolicies();
mKeyRecoveryRules.printPolicies();
mKeyArchivalRules.printPolicies();
}
public String getPolicySubstoreId() {
return mAuthority.getId() + ".Policy";
}
private void setError(IRequest req, String format, String arg) {
if (format == null)
return;
EPolicyException ex = new EPolicyException(format, arg);
Vector ev = req.getExtDataInStringVector(IRequest.ERRORS);
if (ev == null) {
ev = new Vector();
}
ev.addElement(ex.toString());
req.setExtData(IRequest.ERRORS, ev);
}
public Enumeration getPolicyImpls() {
Vector impls = new Vector();
Enumeration enum1 = mImplTable.elements();
Enumeration ret = null;
try {
while (enum1.hasMoreElements()) {
RegisteredPolicy regPolicy =
(RegisteredPolicy) enum1.nextElement();
// Make an Instance of it
IPolicyRule ruleImpl = (IPolicyRule)
Class.forName(regPolicy.getClassPath()).newInstance();
impls.addElement(ruleImpl);
}
ret = impls.elements();
} catch (Exception e) {
Debug.printStackTrace(e);
}
return ret;
}
public Enumeration getPolicyImplsInfo() {
Vector impls = new Vector();
Enumeration enum1 = mImplTable.elements();
Enumeration ret = null;
try {
while (enum1.hasMoreElements()) {
RegisteredPolicy regPolicy =
(RegisteredPolicy) enum1.nextElement();
impls.addElement(regPolicy.getId());
}
ret = impls.elements();
} catch (Exception e) {
Debug.printStackTrace(e);
}
return ret;
}
public IPolicyRule getPolicyImpl(String id) {
RegisteredPolicy regImpl = (RegisteredPolicy)
mImplTable.get(id);
if (regImpl == null)
return null;
IPolicyRule impl = null;
try {
impl =
(IPolicyRule) Class.forName(regImpl.getClassPath()).newInstance();
} catch (Exception e) {
Debug.printStackTrace(e);
}
return impl;
}
public Vector getPolicyImplConfig(String id) {
IPolicyRule rp = getPolicyImpl(id);
if (rp == null)
return null;
Vector v = rp.getDefaultParams();
if (v == null)
v = new Vector();
v.insertElementAt(IPolicyRule.PROP_ENABLE + "=" + "true", 0);
v.insertElementAt(IPolicyRule.PROP_PREDICATE + "=" + " ", 1);
return v;
}
public void deletePolicyImpl(String id)
throws EBaseException {
// First check if the id is valid;
RegisteredPolicy regPolicy =
(RegisteredPolicy) mImplTable.get(id);
if (regPolicy == null)
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL", id));
// If any instance exists for this impl, can't delete it.
boolean instanceExist = false;
Enumeration e = mInstanceTable.elements();
for (; e.hasMoreElements();) {
PolicyInstance inst = (PolicyInstance) e.nextElement();
if (inst.isInstanceOf(id)) {
instanceExist = true;
break;
}
}
if (instanceExist) // we found an instance
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_ACTIVE_POLICY_RULES_EXIST", id));
// Else delete the implementation
mImplTable.remove(id);
IConfigStore policyStore =
mGlobalStore.getSubStore(getPolicySubstoreId());
IConfigStore implStore =
policyStore.getSubStore(PROP_IMPL);
implStore.removeSubStore(id);
// committing
try {
mGlobalStore.commit(true);
} catch (Exception ex) {
Debug.printStackTrace(ex);
String[] params = {"implementation", id};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_DELETING_POLICY_ERROR", params));
}
}
public void addPolicyImpl(String id, String classPath)
throws EBaseException {
// See if the id is unique
if (mImplTable.containsKey(id))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_DUPLICATE_IMPL_ID", id));
// See if the classPath is ok
Object impl = null;
try {
impl = Class.forName(classPath).newInstance();
}catch (Exception e) {
throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL",
id));
}
// Does the class implement one of the four interfaces?
if (!(impl instanceof IEnrollmentPolicy) &&
!(impl instanceof IRenewalPolicy) &&
!(impl instanceof IRevocationPolicy) &&
!(impl instanceof IKeyRecoveryPolicy) &&
!(impl instanceof IKeyArchivalPolicy))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL", classPath));
// Add the implementation to the registry
RegisteredPolicy regPolicy =
new RegisteredPolicy(id, classPath);
mImplTable.put(id, regPolicy);
// Store the impl in the configuration.
IConfigStore policyStore =
mGlobalStore.getSubStore(getPolicySubstoreId());
IConfigStore implStore =
policyStore.getSubStore(PROP_IMPL);
IConfigStore newStore = implStore.makeSubStore(id);
newStore.put(PROP_CLASS, classPath);
try {
mGlobalStore.commit(true);
} catch (Exception e) {
String[] params = {"implementation", id};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_ADDING_POLICY_ERROR", params));
}
}
public Enumeration getPolicyInstances() {
Vector rules = new Vector();
Enumeration enum1 = mPolicyOrder.elements();
Enumeration ret = null;
try {
while (enum1.hasMoreElements()) {
PolicyInstance instance =
(PolicyInstance) mInstanceTable.get((String) enum1.nextElement());
rules.addElement(instance.getRule());
}
ret = rules.elements();
} catch (Exception e) {
Debug.printStackTrace(e);
}
return ret;
}
public Enumeration getPolicyInstancesInfo() {
Vector rules = new Vector();
Enumeration enum1 = mPolicyOrder.elements();
Enumeration ret = null;
try {
while (enum1.hasMoreElements()) {
String ruleName = (String) enum1.nextElement();
PolicyInstance instance =
(PolicyInstance) mInstanceTable.get(ruleName);
rules.addElement(instance.getRuleInfo());
}
ret = rules.elements();
} catch (Exception e) {
Debug.printStackTrace(e);
}
return ret;
}
public IPolicyRule getPolicyInstance(String id) {
PolicyInstance policyInstance = (PolicyInstance)
mInstanceTable.get(id);
return (policyInstance == null) ? null : policyInstance.getRule();
}
public Vector getPolicyInstanceConfig(String id) {
PolicyInstance policyInstance = (PolicyInstance)
mInstanceTable.get(id);
if (policyInstance == null)
return null;
Vector v = policyInstance.getRule().getInstanceParams();
if (v == null)
v = new Vector();
v.insertElementAt(PROP_IMPL_NAME + "=" + policyInstance.getImplId(), 0);
v.insertElementAt(PROP_ENABLE + "=" + policyInstance.isActive(), 1);
String predicate = " ";
if (policyInstance.getRule().getPredicate() != null)
predicate = policyInstance.getRule().getPredicate().toString();
v.insertElementAt(PROP_PREDICATE + "=" + predicate, 2);
return v;
}
public void deletePolicyInstance(String id)
throws EBaseException {
// If the rule is a persistent rule, we can't delete it.
if (mUndeletablePolicies.containsKey(id))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_CANT_DELETE_PERSISTENT_POLICY", id));
// First check if the instance is present.
PolicyInstance instance =
(PolicyInstance) mInstanceTable.get(id);
if (instance == null)
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_INSTANCE", id));
IConfigStore policyStore =
mGlobalStore.getSubStore(getPolicySubstoreId());
IConfigStore instanceStore =
policyStore.getSubStore(PROP_RULE);
instanceStore.removeSubStore(id);
// Remove the rulename from the rder list
int index = mPolicyOrder.indexOf(id);
mPolicyOrder.removeElement(id);
// Now change the ordering in the config file.
policyStore.put(PROP_ORDER, getRuleOrderString(mPolicyOrder));
// Commit changes to file.
try {
mGlobalStore.commit(true);
} catch (Exception e) {
// Put the rule back in the rule order vector.
mPolicyOrder.insertElementAt(id, index);
Debug.printStackTrace(e);
String[] params = {"instance", id};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_DELETING_POLICY_ERROR", params));
}
IPolicyRule rule = instance.getRule();
if (rule instanceof IEnrollmentPolicy)
mEnrollmentRules.removeRule(id);
if (rule instanceof IRenewalPolicy)
mRenewalRules.removeRule(id);
if (rule instanceof IRevocationPolicy)
mRevocationRules.removeRule(id);
if (rule instanceof IKeyRecoveryPolicy)
mKeyRecoveryRules.removeRule(id);
if (rule instanceof IKeyArchivalPolicy)
mKeyArchivalRules.removeRule(id);
// Delete the instance
mInstanceTable.remove(id);
}
public void addPolicyInstance(String id, Hashtable ht)
throws EBaseException {
// The instance id should be unique
if (getPolicyInstance(id) != null)
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_DUPLICATE_INST_ID", id));
// There should be an implmentation for this rule.
String implName = (String) ht.get(IPolicyRule.PROP_IMPLNAME);
// See if there is an implementation with this name.
IPolicyRule rule = getPolicyImpl(implName);
if (rule == null)
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_NO_POLICY_IMPL", implName));
// Prepare config file entries.
IConfigStore policyStore =
mGlobalStore.getSubStore(getPolicySubstoreId());
IConfigStore instanceStore =
policyStore.getSubStore(PROP_RULE);
IConfigStore newStore = instanceStore.makeSubStore(id);
for (Enumeration keys = ht.keys(); keys.hasMoreElements();) {
String key = (String) keys.nextElement();
String val = (String) ht.get(key);
newStore.put(key, val);
}
// Set the order string.
policyStore.put(PROP_ORDER,
getRuleOrderString(mPolicyOrder, id));
// Try to initialize this rule.
rule.init(this, newStore);
// Add the rule to the table.
String enabledStr = (String) ht.get(IPolicyRule.PROP_ENABLE);
boolean active = false;
if (enabledStr == null || enabledStr.trim().length() == 0 ||
enabledStr.equalsIgnoreCase("true"))
active = true;
// Set the predicate if any present on the rule.
String predicate = ((String) ht.get(IPolicyRule.PROP_PREDICATE)).trim();
IExpression exp = null;
if (predicate.trim().length() > 0)
exp = PolicyPredicateParser.parse(predicate.trim());
rule.setPredicate(exp);
// Store the changes in the file.
try {
mGlobalStore.commit(true);
} catch (Exception e) {
String[] params = {"instance", id};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_ADDING_POLICY_ERROR", params));
}
// Add the rule to the instance table.
PolicyInstance policyInst = new PolicyInstance(id, implName,
rule, active);
mInstanceTable.put(id, policyInst);
// Add the rule to the end of order table.
mPolicyOrder.addElement(id);
// If the rule is not active, return.
if (!active)
return;
addRule(id, rule);
}
public void modifyPolicyInstance(String id, Hashtable ht)
throws EBaseException {
// The instance id should be there already
PolicyInstance policyInstance = (PolicyInstance)
mInstanceTable.get(id);
if (policyInstance == null)
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_INSTANCE", id));
IPolicyRule rule = policyInstance.getRule();
// The impl id shouldn't change
String implId = (String) ht.get(IPolicyRule.PROP_IMPLNAME);
if (!implId.equals(policyInstance.getImplId()))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_IMPLCHANGE_ERROR", id));
// Make a new rule instance
IPolicyRule newRule = getPolicyImpl(implId);
if (newRule == null) // Can't happen, but just in case..
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_IMPL", implId));
// Try to init this rule.
IConfigStore policyStore =
mGlobalStore.getSubStore(getPolicySubstoreId());
IConfigStore instanceStore =
policyStore.getSubStore(PROP_RULE);
IConfigStore oldStore = instanceStore.getSubStore(id);
IConfigStore newStore = new PropConfigStore(id);
// See if the rule is disabled.
String enabledStr = (String) ht.get(IPolicyRule.PROP_ENABLE);
boolean active = false;
if (enabledStr == null || enabledStr.trim().length() == 0 ||
enabledStr.equalsIgnoreCase("true"))
active = true;
// Set the predicate expression.
String predicate = ((String) ht.get(IPolicyRule.PROP_PREDICATE)).trim();
IExpression exp = null;
if (predicate.trim().length() > 0)
exp = PolicyPredicateParser.parse(predicate.trim());
// See if this a persistent rule.
if (mUndeletablePolicies.containsKey(id)) {
// A persistent rule can't be disabled.
if (!active) {
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_INACTIVE", id));
}
IExpression defPred = (IExpression)
mUndeletablePolicies.get(id);
if (defPred == SimpleExpression.NULL_EXPRESSION)
defPred = null;
if (exp == null && defPred != null) {
String[] params = {id, defPred.toString(),
"null" };
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
} else if (exp != null && defPred == null) {
String[] params = {id, "null", exp.toString()};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
} else if (exp != null && defPred != null) {
if (!defPred.toString().equals(exp.toString())) {
String[] params = {id, defPred.toString(),
exp.toString() };
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_PERSISTENT_RULE_MISCONFIG", params));
}
}
}
// Predicate for the persistent rule can't be changed.
ht.put(IPolicyRule.PROP_ENABLE, String.valueOf(active));
// put old config store parameters first.
for (Enumeration oldkeys = oldStore.keys();
oldkeys.hasMoreElements();) {
String k = (String) oldkeys.nextElement();
String v = (String) oldStore.getString(k);
newStore.put(k, v);
}
// put modified params.
for (Enumeration newkeys = ht.keys();
newkeys.hasMoreElements();) {
String k = (String) newkeys.nextElement();
String v = (String) ht.get(k);
Debug.trace("newstore key " + k + "=" + v);
if (v != null) {
if (!k.equals(Constants.OP_TYPE) && !k.equals(Constants.OP_SCOPE) &&
!k.equals(Constants.RS_ID) && !k.equals("RULENAME")) {
Debug.trace("newstore.put(" + k + "=" + v + ")");
newStore.put(k, v);
}
}
}
// include impl default params in case we missed any.
/*
for (Enumeration keys = ht.keys(); keys.hasMoreElements();)
{
String key = (String)keys.nextElement();
String val = (String)ht.get(key);
newStore.put(key, val);
}
*/
// Try to initialize this rule.
newRule.init(this, newStore);
// If we are successfully initialized, replace the rule
// instance
policyInstance.setRule(newRule);
policyInstance.setActive(active);
// Set the predicate expression.
if (exp != null)
newRule.setPredicate(exp);
// Store the changes in the file.
try {
for (Enumeration e = newStore.keys(); e.hasMoreElements();) {
String key = (String) e.nextElement();
if (key != null) {
Debug.trace(
"oldstore.put(" + key + "," +
(String) newStore.getString(key) + ")");
oldStore.put(key, (String) newStore.getString(key));
}
}
mGlobalStore.commit(true);
} catch (Exception e) {
String[] params = {"instance", id};
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_ADDING_POLICY_ERROR", params));
}
// If rule is disabled, we need to remove it from the
// policy set.
if (!active) {
if (rule instanceof IEnrollmentPolicy)
mEnrollmentRules.removeRule(id);
if (rule instanceof IRenewalPolicy)
mRenewalRules.removeRule(id);
if (rule instanceof IRevocationPolicy)
mRevocationRules.removeRule(id);
if (rule instanceof IKeyRecoveryPolicy)
mKeyRecoveryRules.removeRule(id);
if (rule instanceof IKeyArchivalPolicy)
mKeyArchivalRules.removeRule(id);
} else // replace the rule
{
if (rule instanceof IEnrollmentPolicy)
mEnrollmentRules.replaceRule(id, newRule);
if (rule instanceof IRenewalPolicy)
mRenewalRules.replaceRule(id, newRule);
if (rule instanceof IRevocationPolicy)
mRevocationRules.replaceRule(id, newRule);
if (rule instanceof IKeyRecoveryPolicy)
mKeyRecoveryRules.replaceRule(id, newRule);
if (rule instanceof IKeyArchivalPolicy)
mKeyArchivalRules.replaceRule(id, newRule);
}
}
public synchronized void changePolicyInstanceOrdering(
String policyOrderStr)
throws EBaseException {
Vector policyOrder = new Vector();
StringTokenizer tokens = new StringTokenizer(policyOrderStr, ",");
// Get all the elements
while (tokens.hasMoreTokens()) {
String instanceId = tokens.nextToken().trim();
// Check if we have that instance configured.
if (!mInstanceTable.containsKey(instanceId))
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_INSTANCE", instanceId));
policyOrder.addElement(instanceId);
}
// Now enforce the new ordering
// First if the order is the same as what we have,
// return.
if (policyOrder.size() == mPolicyOrder.size()) {
if (areSameVectors(policyOrder, mPolicyOrder))
return;
}
PolicySet enrollmentRules = new PolicySet("EnrollmentRules");
PolicySet renewalRules = new PolicySet("RenewalRules");
PolicySet revocationRules = new PolicySet("RevocationRules");
PolicySet keyRecoveryRules = new PolicySet("KeyRecoveryRules");
PolicySet keyArchivalRules = new PolicySet("KeyArchivalRules");
// add system default rules first.
try {
for (int i = 0; i < mSystemDefaults.length; i++) {
String defRuleName = mSystemDefaults[i].substring(
mSystemDefaults[i].lastIndexOf('.') + 1);
IPolicyRule defRule = (IPolicyRule)
Class.forName(mSystemDefaults[i]).newInstance();
IConfigStore ruleConfig =
mConfig.getSubStore(PROP_DEF_POLICIES + "." + defRuleName);
defRule.init(this, ruleConfig);
if (defRule instanceof IEnrollmentPolicy)
enrollmentRules.addRule(defRuleName, defRule);
else if (defRule instanceof IRenewalPolicy)
renewalRules.addRule(defRuleName, defRule);
else if (defRule instanceof IRevocationPolicy)
revocationRules.addRule(defRuleName, defRule);
else if (defRule instanceof IKeyRecoveryPolicy)
keyRecoveryRules.addRule(defRuleName, defRule);
else if (defRule instanceof IKeyArchivalPolicy)
keyArchivalRules.addRule(defRuleName, defRule);
// else ignore the darned rule.
}
} catch (Throwable e) {
Debug.printStackTrace(e);
EBaseException ex = new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
"Cannot create default policy rule. Error: " + e.getMessage()));
mAuthority.log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_POLICY_DEF_CREATE", e.toString()));
throw ex;
}
// add rules specified in the new order.
for (Enumeration enum1 = policyOrder.elements();
enum1.hasMoreElements();) {
String instanceName = (String) enum1.nextElement();
PolicyInstance pInstance = (PolicyInstance)
mInstanceTable.get(instanceName);
if (!pInstance.isActive())
continue;
// Add the rule to the policy set according to category if a
// rule is enabled.
IPolicyRule rule = pInstance.getRule();
if (rule instanceof IEnrollmentPolicy)
enrollmentRules.addRule(instanceName, rule);
else if (rule instanceof IRenewalPolicy)
renewalRules.addRule(instanceName, rule);
else if (rule instanceof IRevocationPolicy)
revocationRules.addRule(instanceName, rule);
else if (rule instanceof IKeyRecoveryPolicy)
keyRecoveryRules.addRule(instanceName, rule);
else if (rule instanceof IKeyArchivalPolicy)
keyArchivalRules.addRule(instanceName, rule);
// else ignore the darned rule.
}
mEnrollmentRules = enrollmentRules;
mRenewalRules = renewalRules;
mRevocationRules = revocationRules;
mKeyRecoveryRules = keyRecoveryRules;
mKeyArchivalRules = keyArchivalRules;
mPolicyOrder = policyOrder;
// Now change the ordering in the config file.
IConfigStore policyStore =
mGlobalStore.getSubStore(getPolicySubstoreId());
policyStore.put(PROP_ORDER, policyOrderStr);
// committing
try {
mGlobalStore.commit(true);
} catch (Exception ex) {
Debug.printStackTrace(ex);
throw new EPolicyException(
CMS.getUserMessage("CMS_POLICY_ORDER_ERROR", policyOrderStr));
}
}
private boolean areSameVectors(Vector v1, Vector v2) {
if (v1.size() != v2.size())
return false;
int size = v1.size();
int i = 0;
for (; i < size; i++)
if (v2.indexOf(v1.elementAt(i)) != i)
break;
return (i == size ? true : false);
}
private String getRuleOrderString(Vector rules) {
StringBuffer sb = new StringBuffer();
for (Enumeration e = rules.elements(); e.hasMoreElements();) {
sb.append((String) e.nextElement());
sb.append(",");
}
if (sb.length() > 0)
sb.setLength(sb.length() - 1);
return new String(sb);
}
private String getRuleOrderString(Vector rules, String newRule) {
String currentRules = getRuleOrderString(rules);
if (currentRules == null || currentRules.length() == 0)
return newRule;
else
return currentRules + "," + newRule;
}
/**
* Initializes the default system policies. Currently there is only
* one policy - ManualAuthentication. More may be added later on.
*
* The default policies may be disabled - for example to over-ride
* agent approval for testing the system by setting the following
* property in the config file:
*
*