diff options
Diffstat (limited to 'base/tps/src/org/dogtagpki/server')
6 files changed, 127 insertions, 82 deletions
diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java b/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java index 2d415c16c..ea765da02 100644 --- a/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java +++ b/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.dogtagpki.server.tps.authentication.AuthenticationManager; import org.dogtagpki.server.tps.cms.ConnectionManager; import org.dogtagpki.server.tps.config.AuthenticatorDatabase; @@ -36,6 +37,7 @@ import org.dogtagpki.server.tps.dbs.TokenDatabase; import org.dogtagpki.server.tps.dbs.TokenRecord; import org.dogtagpki.server.tps.engine.TPSEngine; import org.dogtagpki.server.tps.mapping.MappingResolverManager; +import org.dogtagpki.tps.main.TPSException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.CryptoManager.NotInitializedException; import org.mozilla.jss.crypto.ObjectNotFoundException; @@ -51,6 +53,7 @@ import com.netscape.certsrv.logging.ILogger; import com.netscape.certsrv.request.IRequestListener; import com.netscape.certsrv.request.IRequestQueue; import com.netscape.certsrv.tps.token.TokenStatus; +import com.netscape.cmscore.base.FileConfigStore; import com.netscape.cmscore.dbs.DBSubsystem; /** @@ -81,7 +84,9 @@ public class TPSSubsystem implements IAuthority, ISubsystem { public TPSEngine engine; public TPSTokendb tdb; - public Map<TokenStatus, Collection<TokenStatus>> allowedTransitions = new HashMap<TokenStatus, Collection<TokenStatus>>(); + + public Map<TokenStatus, Collection<TokenStatus>> uiTransitions; + public Map<TokenStatus, Collection<TokenStatus>> operationTransitions; @Override public String getId() { @@ -116,45 +121,109 @@ public class TPSSubsystem implements IAuthority, ISubsystem { profileDatabase = new ProfileDatabase(); profileMappingDatabase = new ProfileMappingDatabase(); - CMS.debug("TokenSubsystem: allowed transitions:"); + FileConfigStore defaultConfig = new FileConfigStore("/usr/share/pki/tps/conf/CS.cfg"); + + uiTransitions = loadAndValidateTokenStateTransitions( + defaultConfig, cs, TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS); + + operationTransitions = loadAndValidateTokenStateTransitions( + defaultConfig, cs, TPSEngine.CFG_OPERATIONS_ALLOWED_TRANSITIONS); + + tdb = new TPSTokendb(this); + + engine = new TPSEngine(); + engine.init(); + } + + public Map<TokenStatus, Collection<TokenStatus>> loadTokenStateTransitions(IConfigStore cs, String property) throws EBaseException { + + String value = cs.getString(property); - // initialize allowed token state transitions with empty containers + if (StringUtils.isEmpty(value)) { + CMS.debug("Missing token state transitions in " + property); + throw new EBaseException("Missing token state transition in " + property); + } + + Map<TokenStatus, Collection<TokenStatus>> transitions = new HashMap<TokenStatus, Collection<TokenStatus>>(); + + // initialize list with empty containers for (TokenStatus state : TokenStatus.values()) { - allowedTransitions.put(state, new LinkedHashSet<TokenStatus>()); + transitions.put(state, new LinkedHashSet<TokenStatus>()); } - // load allowed token state transitions from TPS configuration - for (String transition : cs.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) { + for (String transition : value.split(",")) { + String states[] = transition.split(":"); + if (states.length < 2) { + CMS.debug("Invalid token state transition in " + property + ": " + transition); + throw new EBaseException("Invalid token state transition in " + property + ": " + transition); + } - TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0])); - TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1])); - CMS.debug("TokenSubsystem: - " + fromState + " to " + toState); + TokenStatus currentState = TokenStatus.fromInt(Integer.valueOf(states[0])); + TokenStatus nextState = TokenStatus.fromInt(Integer.valueOf(states[1])); - Collection<TokenStatus> nextStates = allowedTransitions.get(fromState); - nextStates.add(toState); + String info = currentState + " to " + nextState + + " (" + currentState.getValue() + ":" + nextState.getValue() + ")"; + CMS.debug("TokenSubsystem: - " + info); + + Collection<TokenStatus> nextStates = transitions.get(currentState); + nextStates.add(nextState); } - tdb = new TPSTokendb(this); + return transitions; + } - engine = new TPSEngine(); - engine.init(); + public void validateTokenStateTransitions( + Map<TokenStatus, Collection<TokenStatus>> defaultConfig, + Map<TokenStatus, Collection<TokenStatus>> userConfig) throws EBaseException { + for (TokenStatus currentState : userConfig.keySet()) { + Collection<TokenStatus> nextStates = userConfig.get(currentState); + Collection<TokenStatus> defaultNextStates = defaultConfig.get(currentState); + + for (TokenStatus nextState : nextStates) { + if (!defaultNextStates.contains(nextState)) { + String info = currentState + " to " + nextState + + " (" + currentState.getValue() + ":" + nextState.getValue() + ")"; + throw new EBaseException("Unsupported token state transition: " + info); + } + } + } } + public Map<TokenStatus, Collection<TokenStatus>> loadAndValidateTokenStateTransitions( + IConfigStore defaultConfig, + IConfigStore userDefinedConfig, + String property) throws EBaseException { + + CMS.debug("TokenSubsystem: Loading transitions in " + property); + + CMS.debug("TokenSubsystem: * default transitions:"); + Map<TokenStatus, Collection<TokenStatus>> defaultTransitions = + loadTokenStateTransitions(defaultConfig, property); + + CMS.debug("TokenSubsystem: * user-defined transitions:"); + Map<TokenStatus, Collection<TokenStatus>> userDefinedTransitions = + loadTokenStateTransitions(userDefinedConfig, property); + + CMS.debug("TokenSubsystem: Validating transitions in " + property); + validateTokenStateTransitions(defaultTransitions, userDefinedTransitions); + + return userDefinedTransitions; + } /** - * Return the allowed next states for a given token based on TPS configuration. + * Return the allowed next states for changing token state via Web UI or CLI. * - * If the current state is SUSPENDED, token will be allowed transition to either - * FORMATTED or ACTIVE depending on whether the token has certificates. + * If the current state is SUSPENDED, token will be allowed to transition to + * either FORMATTED or ACTIVE depending on whether the token has certificates. * * @param tokenRecord * @return A non-null collection of allowed next token states. */ - public Collection<TokenStatus> getNextTokenStates(TokenRecord tokenRecord) throws Exception { + public Collection<TokenStatus> getUINextTokenStates(TokenRecord tokenRecord) throws TPSException { TokenStatus currentState = tokenRecord.getTokenStatus(); - Collection<TokenStatus> nextStates = allowedTransitions.get(currentState); + Collection<TokenStatus> nextStates = uiTransitions.get(currentState); if (currentState == TokenStatus.SUSPENDED) { @@ -180,6 +249,17 @@ public class TPSSubsystem implements IAuthority, ISubsystem { return nextStates; } + /** + * Return the allowed next states for TPS token operations (i.e. format and enrollment). + * + * @param tokenRecord + * @return A non-null collection of allowed next token states. + */ + public Collection<TokenStatus> getOperationNextTokenStates(TokenRecord tokenRecord) { + TokenStatus currentState = tokenRecord.getTokenStatus(); + return operationTransitions.get(currentState); + } + @Override public void startup() throws EBaseException { CMS.debug("TPSSubsystem: startup() begins"); @@ -296,4 +376,14 @@ public class TPSSubsystem implements IAuthority, ISubsystem { public TPSEngine getEngine() { return engine; } + + public boolean isUITransitionAllowed(TokenRecord tokenRecord, TokenStatus nextState) throws Exception { + Collection<TokenStatus> nextStates = getUINextTokenStates(tokenRecord); + return nextStates.contains(nextState); + } + + public boolean isOperationTransitionAllowed(TokenRecord tokenRecord, TokenStatus nextState) { + Collection<TokenStatus> nextStates = getOperationNextTokenStates(tokenRecord); + return nextStates.contains(nextState); + } } diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java index 7997cc579..ed7e022fa 100644 --- a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java +++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java @@ -64,7 +64,7 @@ public class TPSTokendb { TokenStatus currentTokenStatus = tokenRecord.getTokenStatus(); CMS.debug("TokenRecord.isTransitionAllowed(): current status: " + currentTokenStatus); - Collection<TokenStatus> nextStatuses = tps.getNextTokenStates(tokenRecord); + Collection<TokenStatus> nextStatuses = tps.getUINextTokenStates(tokenRecord); CMS.debug("TokenRecord.isTransitionAllowed(): allowed next statuses: " + nextStatuses); if (!nextStatuses.contains(newState)) { diff --git a/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java b/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java index a577a7619..a5fbc3b7d 100644 --- a/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java +++ b/base/tps/src/org/dogtagpki/server/tps/engine/TPSEngine.java @@ -37,8 +37,6 @@ import org.dogtagpki.tps.msg.EndOpMsg.TPSStatus; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.base.IConfigStore; -import com.netscape.certsrv.tps.token.TokenStatus; public class TPSEngine { @@ -195,8 +193,6 @@ public class TPSEngine { public static final String ENROLL_MODE_RECOVERY = RECOVERY_OP; public static final String ERNOLL_MODE_RENEWAL = RENEWAL_OP; - private static String transitionList; - public void init() { //ToDo } @@ -589,51 +585,4 @@ public class TPSEngine { return resp; } - - //Check to see if special operations transition is allowed - - public boolean isOperationTransitionAllowed(TokenStatus oldState, TokenStatus newState) throws TPSException { - boolean allowed = true; - - if (transitionList == null) { - - IConfigStore configStore = CMS.getConfigStore(); - - String transConfig = CFG_OPERATIONS_ALLOWED_TRANSITIONS; - - CMS.debug("TPSEngine.isOperationTransistionAllowed: getting config: " + transConfig); - try { - transitionList = configStore.getString(transConfig, null); - } catch (EBaseException e) { - throw new TPSException( - "TPSProcessor.isOperationTransitionAllowed: Internal error getting config value for operations transition list!", - TPSStatus.STATUS_ERROR_MISCONFIGURATION); - } - - if (transitionList == null) { - throw new TPSException( - "TPSProcessor.isOperationTransitionAllowed: Can't find non null config value for operations transition list!", - TPSStatus.STATUS_ERROR_MISCONFIGURATION); - } - - CMS.debug("TPSEngine.isOperationTransistionAllowed: transitionList is: " + transitionList); - - } - - String transition = oldState.getValue() + ":" + newState.getValue(); - - CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition); - - if (transitionList.indexOf(transition) == -1) { - CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition); - allowed = false; - } - - CMS.debug("TPSEngine.isOperationTransistionAllowed: checking for transition: " + transition + " allowed: " - + allowed); - - return allowed; - - } - } diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java index bbdc15b86..66407e3a3 100644 --- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java +++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSEnrollProcessor.java @@ -282,7 +282,7 @@ public class TPSEnrollProcessor extends TPSProcessor { TokenStatus newState = TokenStatus.ACTIVE; // Check for transition to ACTIVE status. - if (!tps.engine.isOperationTransitionAllowed(tokenRecord.getTokenStatus(), newState)) { + if (!tps.isOperationTransitionAllowed(tokenRecord, newState)) { CMS.debug(method + " token transition disallowed " + tokenRecord.getTokenStatus() + " to " + newState); diff --git a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java index aa2f24260..e8608c487 100644 --- a/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java +++ b/base/tps/src/org/dogtagpki/server/tps/processor/TPSProcessor.java @@ -33,8 +33,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import netscape.security.x509.RevocationReason; - import org.dogtagpki.server.tps.TPSSession; import org.dogtagpki.server.tps.TPSSubsystem; import org.dogtagpki.server.tps.authentication.AuthUIParameter; @@ -98,6 +96,8 @@ import com.netscape.certsrv.tps.token.TokenStatus; import com.netscape.cms.servlet.tks.SecureChannelProtocol; import com.netscape.symkey.SessionKey; +import netscape.security.x509.RevocationReason; + public class TPSProcessor { public static final int RESULT_NO_ERROR = 0; @@ -2088,7 +2088,7 @@ public class TPSProcessor { TokenStatus newState = TokenStatus.FORMATTED; // Check for transition to FORMATTED status. - if (!tps.engine.isOperationTransitionAllowed(tokenRecord.getTokenStatus(), newState)) { + if (!tps.isOperationTransitionAllowed(tokenRecord, newState)) { String info = " illegal transition attempted: " + tokenRecord.getTokenStatus() + " to " + newState; CMS.debug("TPSProcessor.format: token transition: " + info); diff --git a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java index 40022a440..1c4285ed7 100644 --- a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java +++ b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.servlet.http.HttpServletRequest; @@ -185,15 +186,23 @@ public class TokenService extends PKIService implements TokenResource { TokenStatus status = tokenRecord.getTokenStatus(); TokenStatusData statusData = new TokenStatusData(); statusData.name = status; - statusData.label = labels.getString(status.toString()); + try { + statusData.label = labels.getString(status.toString()); + } catch (MissingResourceException e) { + statusData.label = status.toString(); + } tokenData.setStatus(statusData); - Collection<TokenStatus> nextStates = subsystem.getNextTokenStates(tokenRecord); + Collection<TokenStatus> nextStates = subsystem.getUINextTokenStates(tokenRecord); Collection<TokenStatusData> nextStatesData = new ArrayList<TokenStatusData>(); for (TokenStatus nextState : nextStates) { TokenStatusData nextStateData = new TokenStatusData(); nextStateData.name = nextState; - nextStateData.label = labels.getString(status + "." + nextState); + try { + nextStateData.label = labels.getString(status + "." + nextState); + } catch (MissingResourceException e) { + nextStateData.label = nextState.toString(); + } nextStatesData.add(nextStateData); } tokenData.setNextStates(nextStatesData); @@ -646,10 +655,7 @@ public class TokenService extends PKIService implements TokenResource { msg = msg + " from " + currentTokenStatus + " to " + tokenStatus; // make sure transition is allowed - Collection<TokenStatus> nextStatuses = subsystem.getNextTokenStates(tokenRecord); - CMS.debug("TokenService.changeTokenStatus(): allowed next statuses: " + nextStatuses); - - if (!nextStatuses.contains(tokenStatus)) { + if (!subsystem.isUITransitionAllowed(tokenRecord, tokenStatus)) { CMS.debug("TokenService.changeTokenStatus(): next status not allowed: " + tokenStatus); Exception ex = new BadRequestException("Invalid token status transition"); auditTokenStateChange(ILogger.FAILURE, oldStatus, |