diff options
author | Endi S. Dewata <edewata@redhat.com> | 2016-03-21 21:40:02 +0100 |
---|---|---|
committer | Endi S. Dewata <edewata@redhat.com> | 2016-03-28 18:59:10 +0200 |
commit | 93179af9333197cbdce843f16c02107b8d1db17e (patch) | |
tree | a0311796ed3c168ad0997b24af457cd79576fba3 /base/tps/src | |
parent | c22d9a99240d2f24eb7b0ee11c3153fa475d47a1 (diff) | |
download | pki-93179af9333197cbdce843f16c02107b8d1db17e.tar.gz pki-93179af9333197cbdce843f16c02107b8d1db17e.tar.xz pki-93179af9333197cbdce843f16c02107b8d1db17e.zip |
Generating TEMP_LOST to UNINITIALIZED/ACTIVE transitions dynamically.
The TPS subsystem has been modified to generate the token state
transitions from TEMP_LOST to UNINITIALIZED or ACTIVE dynamically
depending on whether the token has certificates.
The TEMP_LOST to ACTIVE transition has been removed from the CS.cfg.
Duplicate code that loads the allowed transitions list has been
merged and moved into TPSSubsystem.
https://fedorahosted.org/pki/ticket/1808
Diffstat (limited to 'base/tps/src')
3 files changed, 95 insertions, 128 deletions
diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java b/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java index e8734a9b8..008f61333 100644 --- a/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java +++ b/base/tps/src/org/dogtagpki/server/tps/TPSSubsystem.java @@ -17,6 +17,11 @@ // --- END COPYRIGHT BLOCK --- package org.dogtagpki.server.tps; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; + import org.dogtagpki.server.tps.authentication.AuthenticationManager; import org.dogtagpki.server.tps.cms.ConnectionManager; import org.dogtagpki.server.tps.config.AuthenticatorDatabase; @@ -26,7 +31,9 @@ import org.dogtagpki.server.tps.config.ProfileDatabase; import org.dogtagpki.server.tps.config.ProfileMappingDatabase; import org.dogtagpki.server.tps.dbs.ActivityDatabase; import org.dogtagpki.server.tps.dbs.TPSCertDatabase; +import org.dogtagpki.server.tps.dbs.TPSCertRecord; 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.mozilla.jss.CryptoManager; @@ -43,6 +50,7 @@ import com.netscape.certsrv.dbs.IDBSubsystem; 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.dbs.DBSubsystem; /** @@ -70,8 +78,10 @@ public class TPSSubsystem implements IAuthority, ISubsystem { public ConnectionManager connManager; public AuthenticationManager authManager; public MappingResolverManager mappingResolverManager; + public TPSEngine engine; public TPSTokendb tdb; + public Map<TokenStatus, Collection<TokenStatus>> allowedTransitions = new HashMap<TokenStatus, Collection<TokenStatus>>(); @Override public String getId() { @@ -105,6 +115,26 @@ public class TPSSubsystem implements IAuthority, ISubsystem { connectorDatabase = new ConnectorDatabase(); profileDatabase = new ProfileDatabase(); profileMappingDatabase = new ProfileMappingDatabase(); + + CMS.debug("TokenSubsystem: allowed transitions:"); + + // initialize allowed token state transitions with empty containers + for (TokenStatus state : TokenStatus.values()) { + allowedTransitions.put(state, new LinkedHashSet<TokenStatus>()); + } + + // load allowed token state transitions from TPS configuration + for (String transition : cs.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) { + String states[] = transition.split(":"); + + TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0])); + TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1])); + CMS.debug("TokenSubsystem: - " + fromState + " to " + toState); + + Collection<TokenStatus> nextStates = allowedTransitions.get(fromState); + nextStates.add(toState); + } + tdb = new TPSTokendb(this); engine = new TPSEngine(); @@ -112,6 +142,44 @@ public class TPSSubsystem implements IAuthority, ISubsystem { } + /** + * Return the allowed next states for a given token based on TPS configuration. + * + * If the current state is TEMP_LOST, token will be allowed transition to either + * UNINITIALIZED 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 { + + TokenStatus currentState = tokenRecord.getTokenStatus(); + Collection<TokenStatus> nextStates = allowedTransitions.get(currentState); + + if (currentState == TokenStatus.TEMP_LOST) { + + Collection<TokenStatus> ns = new LinkedHashSet<TokenStatus>(); + + // check token certificates + Collection<TPSCertRecord> certRecords = tdb.tdbGetCertRecordsByCUID(tokenRecord.getId()); + + // if token has no certificates, allow token to become uninitialized again + if (certRecords.isEmpty()) { + ns.add(TokenStatus.UNINITIALIZED); + + } else { // otherwise, allow token to become active again + ns.add(TokenStatus.ACTIVE); + } + + // add the original allowed next states + ns.addAll(nextStates); + + return ns; + } + + return nextStates; + } + @Override public void startup() throws EBaseException { CMS.debug("TPSSubsystem: startup() begins"); diff --git a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java index 15e85fb32..51f496652 100644 --- a/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java +++ b/base/tps/src/org/dogtagpki/server/tps/TPSTokendb.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -31,7 +30,6 @@ import org.dogtagpki.server.tps.cms.CARevokeCertResponse; import org.dogtagpki.server.tps.dbs.ActivityDatabase; import org.dogtagpki.server.tps.dbs.TPSCertRecord; import org.dogtagpki.server.tps.dbs.TokenRecord; -import org.dogtagpki.server.tps.engine.TPSEngine; import org.dogtagpki.server.tps.main.ExternalRegAttrs; import org.dogtagpki.server.tps.main.ExternalRegCertToRecover; import org.dogtagpki.tps.main.TPSException; @@ -48,8 +46,8 @@ import netscape.security.x509.RevocationReason; * TPSTokendb class offers a collection of tokendb management convenience routines */ public class TPSTokendb { + private TPSSubsystem tps; - private Map<TokenStatus, Collection<TokenStatus>> allowedTransitions = new HashMap<TokenStatus, Collection<TokenStatus>>(); public TPSTokendb(TPSSubsystem tps) throws EBaseException { if (tps == null) { @@ -58,44 +56,17 @@ public class TPSTokendb { throw new EBaseException(msg); } this.tps = tps; - try { - initAllowedTransitions(); - } catch (Exception e) { - CMS.debug("TPSTokendb: initAllowedTransitions() failed:" + e); - throw new EBaseException(e.toString()); - } } - void initAllowedTransitions() - throws Exception { - CMS.debug("TPSTokendb.initAllowedTransitions()"); - IConfigStore configStore = CMS.getConfigStore(); - - // load allowed token state transitions - CMS.debug("TPSTokendbs: allowed transitions:"); - - for (String transition : configStore.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) { - String states[] = transition.split(":"); - TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0])); - TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1])); - CMS.debug("TPSTokendb: - " + fromState + " to " + toState); - - Collection<TokenStatus> nextStates = allowedTransitions.get(fromState); - if (nextStates == null) { - nextStates = new HashSet<TokenStatus>(); - allowedTransitions.put(fromState, nextStates); - } - nextStates.add(toState); - } - } - - public boolean isTransitionAllowed(TokenRecord tokenRecord, TokenStatus newState) { + public boolean isTransitionAllowed(TokenRecord tokenRecord, TokenStatus newState) throws Exception { boolean result = false; TokenStatus currentTokenStatus = tokenRecord.getTokenStatus(); + CMS.debug("TokenRecord.isTransitionAllowed(): current status: " + currentTokenStatus); - Collection<TokenStatus> nextStatuses = allowedTransitions.get(currentTokenStatus); + Collection<TokenStatus> nextStatuses = tps.getNextTokenStates(tokenRecord); + CMS.debug("TokenRecord.isTransitionAllowed(): allowed next statuses: " + nextStatuses); - if (nextStatuses == null || !nextStatuses.contains(newState)) { + if (!nextStatuses.contains(newState)) { CMS.debug("TokenRecord.isTransitionAllowed(): next status not allowed: " + newState); result = false; 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 a0ca7add3..958843e5b 100644 --- a/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java +++ b/base/tps/src/org/dogtagpki/server/tps/rest/TokenService.java @@ -24,7 +24,6 @@ import java.net.URLEncoder; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.ResourceBundle; @@ -39,15 +38,12 @@ import javax.ws.rs.core.UriInfo; import org.apache.commons.lang.StringUtils; import org.dogtagpki.server.tps.TPSSubsystem; import org.dogtagpki.server.tps.dbs.ActivityDatabase; -import org.dogtagpki.server.tps.dbs.TPSCertRecord; import org.dogtagpki.server.tps.dbs.TokenDatabase; import org.dogtagpki.server.tps.dbs.TokenRecord; -import org.dogtagpki.server.tps.engine.TPSEngine; import org.jboss.resteasy.plugins.providers.atom.Link; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.BadRequestException; -import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.PKIException; import com.netscape.certsrv.dbs.EDBException; import com.netscape.certsrv.ldap.LDAPExceptionConverter; @@ -77,58 +73,8 @@ public class TokenService extends PKIService implements TokenResource { @Context private HttpServletRequest servletRequest; - public Map<TokenStatus, Collection<TokenStatus>> transitions = new HashMap<TokenStatus, Collection<TokenStatus>>(); - public TokenService() throws Exception { CMS.debug("TokenService.<init>()"); - IConfigStore configStore = CMS.getConfigStore(); - - // load allowed token state transitions - CMS.debug("TokenService: allowed transitions:"); - - for (String transition : configStore.getString(TPSEngine.CFG_TOKENDB_ALLOWED_TRANSITIONS).split(",")) { - String states[] = transition.split(":"); - TokenStatus fromState = TokenStatus.fromInt(Integer.valueOf(states[0])); - TokenStatus toState = TokenStatus.fromInt(Integer.valueOf(states[1])); - CMS.debug("TokenService: - " + fromState + " to " + toState); - - Collection<TokenStatus> nextStates = transitions.get(fromState); - if (nextStates == null) { - nextStates = new HashSet<TokenStatus>(); - transitions.put(fromState, nextStates); - } - nextStates.add(toState); - } - - } - - public TokenStatus getTokenStatus(TokenRecord tokenRecord) { - String status = tokenRecord.getStatus(); - - if ("uninitialized".equals(status)) { - return TokenStatus.UNINITIALIZED; - - } else if ("active".equals(status)) { - return TokenStatus.ACTIVE; - - } else if ("lost".equals(status)) { - String reason = tokenRecord.getReason(); - - if ("keyCompromise".equals(reason)) { - return TokenStatus.PERM_LOST; - - } else if ("destroyed".equals(reason)) { - return TokenStatus.DAMAGED; - - } else if ("onHold".equals(reason)) { - return TokenStatus.TEMP_LOST; - } - - } else if ("terminated".equals(status)) { - return TokenStatus.TERMINATED; - } - - return TokenStatus.PERM_LOST; } public void setTokenStatus(TokenRecord tokenRecord, TokenStatus tokenState, String ipAddress, String remoteUser) @@ -142,33 +88,14 @@ public class TokenService extends PKIService implements TokenResource { break; case ACTIVE: - String origStatus = tokenRecord.getStatus(); - String origReason = tokenRecord.getReason(); - - if (origStatus.equalsIgnoreCase("lost") && - origReason.equalsIgnoreCase("onHold")) { - - Collection<TPSCertRecord> certRecords = tps.tdb.tdbGetCertRecordsByCUID(tokenRecord.getId()); - if (certRecords.isEmpty()) { // token was uninitialized - // restore to uninitialized state - tokenRecord.setStatus("uninitialized"); - tokenRecord.setReason(null); - - } else { // token was active - // unrevoke certs - tps.tdb.unRevokeCertsByCUID(tokenRecord.getId(), ipAddress, remoteUser); - - // restore to active state - tokenRecord.setStatus("active"); - tokenRecord.setReason(null); - } - - } else { - // switch to active state - tokenRecord.setStatus("active"); - tokenRecord.setReason(null); + if (tokenRecord.getTokenStatus() == TokenStatus.TEMP_LOST) { + // unrevoke certs + tps.tdb.unRevokeCertsByCUID(tokenRecord.getId(), ipAddress, remoteUser); } + tokenRecord.setStatus("active"); + tokenRecord.setReason(null); + break; case PERM_LOST: @@ -221,6 +148,8 @@ public class TokenService extends PKIService implements TokenResource { public TokenData createTokenData(TokenRecord tokenRecord) throws Exception { + TPSSubsystem subsystem = (TPSSubsystem) CMS.getSubsystem(TPSSubsystem.ID); + ResourceBundle labels = getResourceBundle("token-states"); TokenData tokenData = new TokenData(); @@ -229,23 +158,21 @@ public class TokenService extends PKIService implements TokenResource { tokenData.setUserID(tokenRecord.getUserID()); tokenData.setType(tokenRecord.getType()); - TokenStatus status = getTokenStatus(tokenRecord); + TokenStatus status = tokenRecord.getTokenStatus(); TokenStatusData statusData = new TokenStatusData(); statusData.name = status; statusData.label = labels.getString(status.toString()); tokenData.setStatus(statusData); - Collection<TokenStatus> nextStates = transitions.get(status); - if (nextStates != null) { - Collection<TokenStatusData> nextStatesData = new ArrayList<TokenStatusData>(); - for (TokenStatus nextState : nextStates) { - TokenStatusData nextStateData = new TokenStatusData(); - nextStateData.name = nextState; - nextStateData.label = labels.getString(status + "." + nextState); - nextStatesData.add(nextStateData); - } - tokenData.setNextStates(nextStatesData); + Collection<TokenStatus> nextStates = subsystem.getNextTokenStates(tokenRecord); + Collection<TokenStatusData> nextStatesData = new ArrayList<TokenStatusData>(); + for (TokenStatus nextState : nextStates) { + TokenStatusData nextStateData = new TokenStatusData(); + nextStateData.name = nextState; + nextStateData.label = labels.getString(status + "." + nextState); + nextStatesData.add(nextStateData); } + tokenData.setNextStates(nextStatesData); tokenData.setAppletID(tokenRecord.getAppletID()); tokenData.setKeyInfo(tokenRecord.getKeyInfo()); @@ -588,7 +515,7 @@ public class TokenService extends PKIService implements TokenResource { TokenDatabase database = subsystem.getTokenDatabase(); tokenRecord = database.getRecord(tokenID); - TokenStatus currentTokenStatus = getTokenStatus(tokenRecord); + TokenStatus currentTokenStatus = tokenRecord.getTokenStatus(); CMS.debug("TokenService.changeTokenStatus(): current status: " + currentTokenStatus); if (currentTokenStatus == tokenStatus) { @@ -601,9 +528,10 @@ public class TokenService extends PKIService implements TokenResource { msg = msg + " from " + currentTokenStatus + " to " + tokenStatus; // make sure transition is allowed - Collection<TokenStatus> nextStatuses = transitions.get(currentTokenStatus); + Collection<TokenStatus> nextStatuses = subsystem.getNextTokenStates(tokenRecord); CMS.debug("TokenService.changeTokenStatus(): allowed next statuses: " + nextStatuses); - if (nextStatuses == null || !nextStatuses.contains(tokenStatus)) { + + if (!nextStatuses.contains(tokenStatus)) { CMS.debug("TokenService.changeTokenStatus(): next status not allowed: " + tokenStatus); throw new BadRequestException("Invalid token status transition"); } |