From e9ab0ec12bc7e22857850a6a183df825154971d4 Mon Sep 17 00:00:00 2001 From: Jack Magne Date: Thu, 30 Aug 2012 17:23:11 -0700 Subject: Bug 844800 - TPS should provide the ability to not allow tokens marked as 'Terminated' to be formatted and reused. --- base/tps/doc/CS.cfg.in | 12 ++- base/tps/src/engine/RA.cpp | 103 +++++++++++++++++++++++++ base/tps/src/include/engine/RA.h | 6 ++ base/tps/src/processor/RA_Enroll_Processor.cpp | 16 +++- base/tps/src/processor/RA_Processor.cpp | 20 +++-- base/tps/src/tus/tus_db.c | 7 +- 6 files changed, 148 insertions(+), 16 deletions(-) diff --git a/base/tps/doc/CS.cfg.in b/base/tps/doc/CS.cfg.in index 838b08fb0..fa403f539 100644 --- a/base/tps/doc/CS.cfg.in +++ b/base/tps/doc/CS.cfg.in @@ -1582,7 +1582,17 @@ tps._002=# tps.cert.list=sslserver,subsystem,audit_signing tps._003=# tps.cert.sslserver.nickname=xxx tps._005=# tps.cert.subsystem.nickname=xxx tps._007=# tps.cert.audit_signing.nickname=xxx -tps._009=######################################## +tps._008=# operations.allowedTransitions: +tps._009=# - token operations, like formatting and enrollment have transitions between the following states +tps._010=# TOKEN_UNINITIALIZED = 0, +tps._011=# TOKEN_DAMAGED =1, +tps._012=# TOKEN_PERM_LOST=2, +tps._013=# TOKEN_TEMP_LOST=3, +tps._014=# TOKEN_FOUND =4, +tps._015=# TOKEN_TEMP_LOST_PERM_LOST =5, +tps._016=# TOKEN_TERMINATED = 6 +tps._017=# Sample: tps.operations.allowedTransitions=0:0,0:4,4:6,6:0 +tps._018=######################################## tps.cert.list=sslserver,subsystem,audit_signing tps.cert.sslserver.nickname=[HSM_LABEL][NICKNAME] tps.cert.subsystem.nickname=[HSM_LABEL][NICKNAME] diff --git a/base/tps/src/engine/RA.cpp b/base/tps/src/engine/RA.cpp index 862b9e105..f8c64f306 100644 --- a/base/tps/src/engine/RA.cpp +++ b/base/tps/src/engine/RA.cpp @@ -178,6 +178,8 @@ const char *RA::CFG_AUDIT_PREFIX = "logging.audit"; const char *RA::CFG_ERROR_PREFIX = "logging.error"; const char *RA::CFG_DEBUG_PREFIX = "logging.debug"; const char *RA::CFG_SELFTEST_PREFIX = "selftests.container.logger"; +const char *RA::CFG_TOKENDB_ALLOWED_TRANSITIONS = "tokendb.allowedTransitions"; +const char *RA::CFG_OPERATIONS_ALLOWED_TRANSITIONS = "tps.operations.allowedTransitions"; const char *RA::CFG_AUTHS_ENABLE="auth.enable"; @@ -195,6 +197,20 @@ typedef Authentication* (*makeauthentication)(); extern void BuildHostPortLists(char *host, char *port, char **hostList, char **portList, int len); +static char *transitionList = NULL; + +#define MAX_TOKEN_UI_STATE 6 + +enum token_ui_states { + TOKEN_UNINITIALIZED = 0, + TOKEN_DAMAGED =1, + TOKEN_PERM_LOST=2, + TOKEN_TEMP_LOST=3, + TOKEN_FOUND =4, + TOKEN_TEMP_LOST_PERM_LOST =5, + TOKEN_TERMINATED = 6 +}; + #ifdef XP_WIN32 #define TPS_PUBLIC __declspec(dllexport) #else /* !XP_WIN32 */ @@ -2821,6 +2837,47 @@ TPS_PUBLIC char *RA::ra_get_cert_tokenType(LDAPMessage *entry) { return get_cert_tokenType(entry); } +TPS_PUBLIC int RA::ra_get_token_status(char *cuid) { + + int rc = -1; + LDAPMessage *entry; + char *status = NULL; + char *reason = NULL; + + int status_int = -1; + //Let's say -1 is unknown; + + if ((rc = find_tus_db_entry(cuid, 0, &entry)) != LDAP_SUCCESS) { + goto loser; + } + + status = ra_get_token_status(entry); + + if (status == NULL) { + goto loser; + } + + reason = ra_get_token_reason(entry); + + status_int = get_token_state(status, reason); + + +loser: + if (entry != NULL) { + ldap_msgfree(entry); + } + + if (status != NULL) { + free(status); + } + + if (reason != NULL) { + free(reason); + } + + return status_int; +} + TPS_PUBLIC char *RA::ra_get_token_status(LDAPMessage *entry) { return get_token_status(entry); } @@ -3622,3 +3679,49 @@ loser: return newKey; } + +bool RA::transition_allowed(int oldState, int newState) +{ + /* parse the allowed transitions string and look for old:new */ + + // See if we need to read in the thing. + + transitionList = (char *) m_cfg->GetConfigAsString(RA::CFG_OPERATIONS_ALLOWED_TRANSITIONS, NULL); + + if (transitionList == NULL) { + transitionList = (char *) m_cfg->GetConfigAsString(RA::CFG_TOKENDB_ALLOWED_TRANSITIONS, NULL); + } + + if (transitionList == NULL) return true; + + char search[128]; + + PR_snprintf(search, 128, "%d:%d", oldState, newState); + return match_comma_list(search, transitionList); + +} + +int RA::get_token_state(char *state, char *reason) +{ + int ret = 0; + if (strcmp(state, STATE_UNINITIALIZED) == 0) { + ret = TOKEN_UNINITIALIZED; + } else if (strcasecmp(state, STATE_ACTIVE) == 0) { + ret = TOKEN_FOUND; + } else if (strcasecmp(state, STATE_LOST) == 0) { + if (strcasecmp(reason, "keyCompromise") == 0) { + /* perm lost or temp -> perm lost */ + ret = TOKEN_PERM_LOST; + } else if (strcasecmp(reason, "destroyed") == 0) { + ret = TOKEN_DAMAGED; + } else if (strcasecmp(reason, "onHold") == 0) { + ret = TOKEN_TEMP_LOST; + } + } else if (strcasecmp(state, "terminated") == 0) { + ret = TOKEN_TERMINATED; + } else { + /* state is disabled or otherwise : what to do here? */ + ret = TOKEN_PERM_LOST; + } + return ret; +} diff --git a/base/tps/src/include/engine/RA.h b/base/tps/src/include/engine/RA.h index 9e7db9857..ea04aa4d5 100644 --- a/base/tps/src/include/engine/RA.h +++ b/base/tps/src/include/engine/RA.h @@ -200,6 +200,7 @@ class RA TPS_PUBLIC static int ra_is_token_pin_resetable(char *cuid); TPS_PUBLIC static int ra_is_token_present(char *cuid); TPS_PUBLIC static int ra_allow_token_reenroll(char *cuid); + TPS_PUBLIC static int ra_get_token_status(char *cuid); TPS_PUBLIC static int ra_allow_token_renew(char *cuid); TPS_PUBLIC static int ra_force_token_format(char *cuid); TPS_PUBLIC static int ra_is_update_pin_resetable_policy(char *cuid); @@ -300,6 +301,8 @@ class RA static const char *CFG_IPUBLISHER_LIB; static const char *CFG_IPUBLISHER_FACTORY; + static const char *CFG_TOKENDB_ALLOWED_TRANSITIONS; + static const char *CFG_OPERATIONS_ALLOWED_TRANSITIONS; public: static const char *TKS_RESPONSE_STATUS; @@ -368,6 +371,9 @@ class RA TPS_PUBLIC static SECCertificateUsage getCertificateUsage(const char *certusage); TPS_PUBLIC static bool verifySystemCertByNickname(const char *nickname, const char *certUsage); TPS_PUBLIC static bool verifySystemCerts(); + + static bool transition_allowed(int oldState, int newState); + static int get_token_state(char *state, char *reason); }; diff --git a/base/tps/src/processor/RA_Enroll_Processor.cpp b/base/tps/src/processor/RA_Enroll_Processor.cpp index d88d84087..ba751646e 100644 --- a/base/tps/src/processor/RA_Enroll_Processor.cpp +++ b/base/tps/src/processor/RA_Enroll_Processor.cpp @@ -1989,11 +1989,19 @@ TPS_PUBLIC RA_Status RA_Enroll_Processor::Process(RA_Session *session, NameValue } if (RA::ra_is_token_present(cuid)) { - RA::Debug(FN, "Found token %s", cuid); - if (RA::ra_is_tus_db_entry_disabled(cuid)) { - RA::Error(FN, "CUID %s Disabled", cuid); + + int token_status = RA::ra_get_token_status(cuid); + + // As far as the ui states, state "enrolled" maps to the state of "FOUND" or 4; + + RA::Debug(FN, "Found token %s status %d", cuid, token_status); + + int STATUS_FOUND = 4; + if (token_status == -1 || !RA::transition_allowed(token_status, STATUS_FOUND)) { + RA::Error(FN, "Operation for CUID %s Disabled illegal transition attempted %d:%d", cuid,token_status, STATUS_FOUND); status = STATUS_ERROR_DISABLED_TOKEN; - PR_snprintf(audit_msg, 512, "token disabled"); + + PR_snprintf(audit_msg, 512, "Operation for CUID %s Disabled, illegal transition attempted %d:%d.", cuid,token_status, STATUS_FOUND); goto loser; } diff --git a/base/tps/src/processor/RA_Processor.cpp b/base/tps/src/processor/RA_Processor.cpp index a9947555b..5395d82b9 100644 --- a/base/tps/src/processor/RA_Processor.cpp +++ b/base/tps/src/processor/RA_Processor.cpp @@ -2753,16 +2753,20 @@ RA_Status RA_Processor::Format(RA_Session *session, NameValueSet *extensions, bo } if (RA::ra_is_token_present(cuid)) { + int token_status = RA::ra_get_token_status(cuid); + RA::Debug("RA_Processor::Format", - "Found token %s", cuid); + "Found token %s status %d", cuid, token_status); - if (RA::ra_is_tus_db_entry_disabled(cuid)) { - RA::Error("RA_Format_Processor::Process", - "CUID %s Disabled", cuid); - status = STATUS_ERROR_DISABLED_TOKEN; - PR_snprintf(audit_msg, 512, "CUID %s Disabled, status=STATUS_ERROR_DISABLED_TOKEN", cuid); - goto loser; - } + // Check for transition to 0/UNINITIALIZED status. + + if (token_status == -1 || !RA::transition_allowed(token_status, 0)) { + RA::Error("RA_Format_Processor::Process", + "Operation for CUID %s Disabled", cuid); + status = STATUS_ERROR_DISABLED_TOKEN; + PR_snprintf(audit_msg, 512, "Operation for CUID %s Disabled, illegal transition attempted %d:%d.", cuid, token_status, 0); + goto loser; + } } else { RA::Debug("RA_Processor::Format", "Not Found token %s", cuid); diff --git a/base/tps/src/tus/tus_db.c b/base/tps/src/tus/tus_db.c index c865bc371..9ae451415 100644 --- a/base/tps/src/tus/tus_db.c +++ b/base/tps/src/tus/tus_db.c @@ -4209,7 +4209,7 @@ TPS_PUBLIC int is_tus_db_entry_disabled(char *cn) LDAPMessage *result = NULL; LDAPMessage *e = NULL; struct berval **v = NULL; - int disabled = 0; + int disabled = 1; int rc = -1; if (cn != NULL && PL_strlen(cn) > 0) { @@ -4218,8 +4218,9 @@ TPS_PUBLIC int is_tus_db_entry_disabled(char *cn) if (e != NULL) { if ((v = ldap_get_values_len(ld, e, TOKEN_STATUS)) != NULL) { if ((valid_berval(v)) && (PL_strlen(v[0]->bv_val) > 0)) { - if (!PL_strcasecmp(v[0]->bv_val, STATE_DISABLED)) { - disabled = 1; + if (!PL_strcasecmp(v[0]->bv_val, STATE_ACTIVE) || + !PL_strcasecmp(v[0], STATE_UNINITIALIZED)) { + disabled = 0; } } if( v != NULL ) { -- cgit