// --- BEGIN COPYRIGHT BLOCK --- // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; // version 2.1 of the License. // // This library 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301 USA // // Copyright (C) 2007 Red Hat, Inc. // All rights reserved. // --- END COPYRIGHT BLOCK --- #include "engine/RA.h" #include "main/Util.h" #include "main/RA_Msg.h" #include "main/RA_Session.h" #include "channel/Secure_Channel.h" #include "processor/RA_Processor.h" #include "processor/RA_Pin_Reset_Processor.h" #include "main/Memory.h" #include "tus/tus_db.h" #define OP_PREFIX "op.pinReset" static const char *expected_version = NULL; #ifdef XP_WIN32 #define TPS_PUBLIC __declspec(dllexport) #else /* !XP_WIN32 */ #define TPS_PUBLIC #endif /* !XP_WIN32 */ /** * Constructs a processor for hanlding pin reset operation. */ TPS_PUBLIC RA_Pin_Reset_Processor::RA_Pin_Reset_Processor() { } /** * Destructs pin reset processor. */ TPS_PUBLIC RA_Pin_Reset_Processor::~RA_Pin_Reset_Processor() { } /** * Process the current session. */ TPS_PUBLIC RA_Status RA_Pin_Reset_Processor::Process(RA_Session *session, NameValueSet *extensions) { struct berval **tokenOwner=NULL; char configname[256]; const char *tokenType = NULL; char *cuid = NULL; const char *msn = NULL; PRIntervalTime start, end; RA_Status status = STATUS_NO_ERROR; int rc = -1; AuthParams *login = NULL; Secure_Channel *channel = NULL; char *new_pin = NULL; unsigned int minlen = 0, maxlen = 0; const char *applet_dir; bool upgrade_enc = false; char curVer[10]; char newVer[10]; char *curKeyInfoStr = NULL; char *newVersionStr = NULL; SecurityLevel security_level = SECURE_MSG_MAC_ENC; Buffer *CardManagerAID = RA::GetConfigStore()->GetConfigAsBuffer( RA::CFG_APPLET_CARDMGR_INSTANCE_AID, RA::CFG_DEF_CARDMGR_INSTANCE_AID); Buffer *NetKeyAID = RA::GetConfigStore()->GetConfigAsBuffer( RA::CFG_APPLET_NETKEY_INSTANCE_AID, RA::CFG_DEF_NETKEY_INSTANCE_AID); int i; Buffer key_data_set; Buffer *token_status = NULL; Buffer *buildID = NULL; char *policy = NULL; char *tmp_policy = NULL; const char* required_version = NULL; const char *appletVersion = NULL; const char *final_applet_version = NULL; char *keyVersion = PL_strdup( "" ); const char *userid = PL_strdup( "" ); BYTE major_version = 0x0; BYTE minor_version = 0x0; BYTE app_major_version = 0x0; BYTE app_minor_version = 0x0; char *token_userid = NULL; Buffer host_challenge = Buffer(8, (BYTE)0); Buffer key_diversification_data; Buffer key_info_data; Buffer card_challenge; Buffer card_cryptogram; Buffer token_cuid; Buffer token_msn; const char *connId = NULL; const char *connid = NULL; const char *tksid = NULL; const char *authid = NULL; AuthParams *authParams = NULL; start = PR_IntervalNow(); Buffer *cplc_data = NULL; char activity_msg[4096]; LDAPMessage *e = NULL; LDAPMessage *ldapResult = NULL; int maxReturns = 10; char audit_msg[512] = ""; char *profile_state = NULL; int key_change_over_success = 0; RA::Debug("RA_Pin_Reset_Processor::Process", "Client %s", session->GetRemoteIP()); RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "RA_Pin_Reset_Processor::Process"); SelectApplet(session, 0x04, 0x00, CardManagerAID); cplc_data = GetData(session); if (cplc_data == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "Get Data Failed"); status = STATUS_ERROR_SECURE_CHANNEL; PR_snprintf(audit_msg, 512, "Get Data Failed, status = STATUS_ERROR_SECURE_CHANNEL"); goto loser; } RA::DebugBuffer("RA_Pin_Reset_Processor::process", "CPLC Data = ", cplc_data); if (cplc_data->size() < 47) { RA::Error("RA_Format_Processor::Process", "Invalid CPLC Size"); status = STATUS_ERROR_SECURE_CHANNEL; PR_snprintf(audit_msg, 512, "Invalid CPLC Size, status = STATUS_ERROR_SECURE_CHANNEL"); goto loser; } token_cuid = Buffer(cplc_data->substr(3,4)) + Buffer(cplc_data->substr(19,2)) + Buffer(cplc_data->substr(15,4)); RA::DebugBuffer("RA_Pin_Reset_Processor::process", "Token CUID= ", &token_cuid); cuid = Util::Buffer2String(token_cuid); token_msn = Buffer(cplc_data->substr(41, 4)); RA::DebugBuffer("RA_Pin_Reset_Processor::process", "Token MSN= ", &token_msn); msn = Util::Buffer2String(token_msn); /** * Checks if the netkey has the required applet version. */ SelectApplet(session, 0x04, 0x00, NetKeyAID); token_status = GetStatus(session, 0x00, 0x00); if (token_status == NULL) { major_version = 0x0; minor_version = 0x0; app_major_version = 0x0; app_minor_version = 0x0; } else { major_version = ((BYTE*)*token_status)[0]; minor_version = ((BYTE*)*token_status)[1]; app_major_version = ((BYTE*)*token_status)[2]; app_minor_version = ((BYTE*)*token_status)[3]; } RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Major=%d Minor=%d", major_version, minor_version); RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Applet Major=%d Applet Minor=%d", app_major_version, app_minor_version); if (!RA::ra_is_token_present(cuid)) { RA::Error("RA_Pin_Reset_Processor::Process", "CUID %s Not Present", cuid); status = STATUS_ERROR_DB; PR_snprintf(audit_msg, 512, "CUID Not Present, status = STATUS_ERROR_DB"); goto loser; } // retrieve CUID if (!GetTokenType(OP_PREFIX, major_version, minor_version, cuid, msn, extensions, status, tokenType)) { PR_snprintf(audit_msg, 512, "Failed to get token type"); goto loser; } // check if profile is enabled PR_snprintf((char *)configname, 256, "config.Profiles.%s.state", tokenType); profile_state = (char *) RA::GetConfigStore()->GetConfigAsString(configname); if ((profile_state != NULL) && (PL_strcmp(profile_state, "Enabled") != 0)) { RA::Error("RA_Pin_Reset_Processor::Process", "Profile %s Disabled for CUID %s", tokenType, cuid); status = STATUS_ERROR_DEFAULT_TOKENTYPE_PARAMS_NOT_FOUND; PR_snprintf(audit_msg, 512, "profile %s disabled", tokenType); goto loser; } if (RA::ra_is_tus_db_entry_disabled(cuid)) { RA::Error("RA_Pin_Reset_Processor::Process", "CUID %s Disabled", cuid); status = STATUS_ERROR_DISABLED_TOKEN; PR_snprintf(audit_msg, 512, "Token disabled, status = STATUS_ERROR_DISABLED_TOKEN"); goto loser; } // we know cuid and msn here RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "token enabled"); if (!RA::ra_is_token_pin_resetable(cuid)) { RA::Error("RA_Pin_Reset_Processor::Process", "CUID %s Cannot Pin Reset", cuid); status = STATUS_ERROR_NOT_PIN_RESETABLE; PR_snprintf(audit_msg, 512, "token cannot pin reset, status = STATUS_ERROR_PIN_RESETABLE"); goto loser; } // we know cuid and msn here RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "pin reset allowed"); PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType); tksid = RA::GetConfigStore()->GetConfigAsString(configname); if (tksid == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "TKS Connection Parameter %s Not Found", configname); status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND; PR_snprintf(audit_msg, 512, "TKS Connection Parameter %s Not Found, status = STATUS_ERROR_DEFAULT_TOKENTYPE_NOT_FOUND", configname); goto loser; } buildID = GetAppletVersion(session); if (buildID == NULL) { PR_snprintf((char *)configname, 256, "%s.%s.update.applet.emptyToken.enable", OP_PREFIX, tokenType); if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) { appletVersion = PL_strdup( "unknown" ); } else { RA::Error("RA_Pin_Reset_Processor::Process", "no applet found and applet upgrade not enabled"); status = STATUS_ERROR_SECURE_CHANNEL; PR_snprintf(audit_msg, 512, "no applet found and applet upgrade not enabled, status = STATUS_ERROR_SECURE_CHANNEL"); goto loser; } } else { char * buildid = Util::Buffer2String(*buildID); RA::Debug("RA_Pin_Reset_Processor", "buildid = %s", buildid); char version[13]; PR_snprintf((char *) version, 13, "%x.%x.%s", app_major_version, app_minor_version, buildid); appletVersion = strdup(version); if (buildid != NULL) { PR_Free(buildid); buildid = NULL; } } final_applet_version = strdup(appletVersion); RA::Debug("RA_Pin_Reset_Processor", "final_applet_version = %s", final_applet_version); /** * Checks if we need to upgrade applet. */ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.enable", OP_PREFIX, tokenType); if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) { PR_snprintf((char *)configname, 256, "%s.%s.update.applet.requiredVersion", OP_PREFIX, tokenType); required_version = RA::GetConfigStore()->GetConfigAsString(configname); expected_version = PL_strdup(required_version); if (expected_version == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "misconfiguration for upgrade"); status = STATUS_ERROR_MISCONFIGURATION; PR_snprintf(audit_msg, 512, "misconfiguration for upgrade, status = STATUS_ERROR_MISCONFIGURATION"); goto loser; } /* Bugscape #55826: used case-insensitive check below */ if (PL_strcasecmp(expected_version, appletVersion) != 0) { /* upgrade applet */ PR_snprintf((char *)configname, 256, "%s.%s.update.applet.directory", OP_PREFIX, tokenType); applet_dir = RA::GetConfigStore()->GetConfigAsString(configname); if (applet_dir == NULL || strlen(applet_dir) == 0) { RA::Error(LL_PER_PDU, "RA_Processor::UpgradeApplet", "Failed to get %s", applet_dir); PR_snprintf(audit_msg, 512, "Failed to get %s", applet_dir); goto loser; } PR_snprintf((char *)configname, 256, "%s.%s.update.applet.encryption", OP_PREFIX, tokenType); upgrade_enc = RA::GetConfigStore()->GetConfigAsBool(configname, true); if (!upgrade_enc) security_level = SECURE_MSG_MAC; PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType); connid = RA::GetConfigStore()->GetConfigAsString(configname); int upgrade_rc = UpgradeApplet(session, (char *) OP_PREFIX, (char*)tokenType, major_version, minor_version, expected_version, applet_dir, security_level, connid, extensions, 30, 70, &keyVersion); if (upgrade_rc != 1) { RA::Error("RA_Pin_Reset_Processor::Process", "upgrade failure"); status = STATUS_ERROR_UPGRADE_APPLET; /** * Bugscape #55709: Re-select Net Key Applet ONLY on failure. */ SelectApplet(session, 0x04, 0x00, NetKeyAID); if (upgrade_rc == -1) { RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE, userid, cuid, msn, "Failure", "pin_reset", keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "failed to setup secure channel"); } else { RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE, userid, cuid, msn, "Success", "pin_reset", keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel"); } RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE, userid, cuid, msn, "Failure", "pin_reset", keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "applet upgrade"); goto loser; } RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE, userid, cuid, msn, "Success", "pin_reset", keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "setup secure channel"); RA::Audit(EV_APPLET_UPGRADE, AUDIT_MSG_APPLET_UPGRADE, userid, cuid, msn, "Success", "pin_reset", keyVersion != NULL? keyVersion : "", appletVersion, expected_version, "applet upgrade"); final_applet_version = expected_version; } } /** * Checks if the netkey has the required key version. */ PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.enable", OP_PREFIX, tokenType); if (RA::GetConfigStore()->GetConfigAsBool(configname, 0)) { PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType); int requiredVersion = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00); PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType); connId = RA::GetConfigStore()->GetConfigAsString(configname); if( channel != NULL ) { delete channel; channel = NULL; } channel = SetupSecureChannel(session, requiredVersion, 0x00 /* default key index */, connId); if (channel == NULL) { /* if version 0x02 key not found, create them */ SelectApplet(session, 0x04, 0x00, CardManagerAID); channel = SetupSecureChannel(session, 0x00, /* default key version */ 0x00 /* default key index */, connId); if (channel == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "setup secure channel failure"); status = STATUS_ERROR_SECURE_CHANNEL; PR_snprintf(audit_msg, 512, "setup secure channel failure, status = STATUS_ERROR_SECURE_CHANNEL"); goto loser; } rc = channel->ExternalAuthenticate(); if (rc != 1) { RA::Error("RA_Pin_Reset_Processor::Process", "External authentication in secure channel failed"); status = STATUS_ERROR_EXTERNAL_AUTH; PR_snprintf(audit_msg, 512, "External authentication in secure channel failed, status = STATUS_ERROR_EXTERNAL_AUTH"); goto loser; } PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType); int v = RA::GetConfigStore()->GetConfigAsInt(configname, 0x00); Buffer curKeyInfo = channel->GetKeyInfoData(); BYTE nv[2] = { v, 0x01 }; Buffer newVersion(nv, 2); PR_snprintf((char *)configname, 256,"%s.%s.tks.conn", OP_PREFIX, tokenType); connid = RA::GetConfigStore()->GetConfigAsString(configname); rc = CreateKeySetData( channel->GetKeyDiversificationData(), curKeyInfo, newVersion, key_data_set, connid); if (rc != 1) { RA::Error("RA_Pin_Reset_Processor::Process", "failed to create new key set"); status = STATUS_ERROR_CREATE_CARDMGR; PR_snprintf(audit_msg, 512, "failed to create new key set, status = STATUS_ERROR_CREATE_CARDMGR"); goto loser; } BYTE curVersion = ((BYTE*)curKeyInfo)[0]; BYTE curIndex = ((BYTE*)curKeyInfo)[1]; rc = channel->PutKeys(session, curVersion, curIndex, &key_data_set); curKeyInfoStr = Util::Buffer2String(curKeyInfo); newVersionStr = Util::Buffer2String(newVersion); if(curKeyInfoStr != NULL && strlen(curKeyInfoStr) >= 2) { curVer[0] = curKeyInfoStr[0]; curVer[1] = curKeyInfoStr[1]; curVer[2] = 0; } else { curVer[0] = 0; } if(newVersionStr != NULL && strlen(newVersionStr) >= 2) { newVer[0] = newVersionStr[0] ; newVer[1] = newVersionStr[1] ; newVer[2] = 0; } else { newVer[0] = 0; } if (rc!=0) { RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Failure", "pin_reset", final_applet_version != NULL ? final_applet_version : "", curVer, newVer, "key changeover failed"); } SelectApplet(session, 0x04, 0x00, NetKeyAID); PR_snprintf((char *)configname, 256, "%s.%s.update.symmetricKeys.requiredVersion", OP_PREFIX, tokenType); if( channel != NULL ) { delete channel; channel = NULL; } PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType); connId = RA::GetConfigStore()->GetConfigAsString(configname); channel = SetupSecureChannel(session, RA::GetConfigStore()->GetConfigAsInt(configname, 0x00), 0x00 /* default key index */, connId); if (channel == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "setup secure channel failure"); status = STATUS_ERROR_CREATE_CARDMGR; PR_snprintf(audit_msg, 512, "setup secure channel failure, status = STATUS_ERROR_CREATE_CARDMGR"); goto loser; } RA::Audit(EV_KEY_CHANGEOVER, AUDIT_MSG_KEY_CHANGEOVER, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "Success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", curVer, newVer, "key changeover"); key_change_over_success = 1; } else { key_change_over_success = 1; } } else { PR_snprintf((char *)configname, 256, "%s.%s.tks.conn", OP_PREFIX, tokenType); connId = RA::GetConfigStore()->GetConfigAsString(configname); if( channel != NULL ) { delete channel; channel = NULL; } channel = SetupSecureChannel(session, 0x00, 0x00 /* default key index */, connId); } /* we should have a good channel here */ if (channel == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "no channel creation failure"); status = STATUS_ERROR_CREATE_CARDMGR; PR_snprintf(audit_msg, 512, "no channel creation failure, status = STATUS_ERROR_CREATE_CARDMGR"); goto loser; } if (channel != NULL) { if( keyVersion != NULL ) { PR_Free( (char *) keyVersion ); keyVersion = NULL; } keyVersion = Util::Buffer2String(channel->GetKeyInfoData()); } PR_snprintf((char *)configname, 256, "%s.%s.loginRequest.enable", OP_PREFIX, tokenType); if (RA::GetConfigStore()->GetConfigAsBool(configname, 1)) { if (extensions != NULL && extensions->GetValue("extendedLoginRequest") != NULL) { RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected"); AuthenticationEntry *entry = GetAuthenticationEntry( OP_PREFIX, configname, tokenType); char **params = NULL; char pb[1024]; char *locale = NULL; if (extensions != NULL && extensions->GetValue("locale") != NULL) { locale = extensions->GetValue("locale"); } else { locale = ( char * ) "en"; /* default to english */ } int n = entry->GetAuthentication()->GetNumOfParamNames(); if (n > 0) { RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected n=%d", n); params = (char **) PR_Malloc(n); for (int i = 0; i < n; i++) { sprintf(pb,"id=%s&name=%s&desc=%s&type=%s&option=%s", entry->GetAuthentication()->GetParamID(i), entry->GetAuthentication()->GetParamName(i, locale), entry->GetAuthentication()->GetParamDescription(i, locale), entry->GetAuthentication()->GetParamType(i), entry->GetAuthentication()->GetParamOption(i) ); params[i] = PL_strdup(pb); RA::Debug("RA_Enroll_Processor::RequestUserId", "params[i]=%s", params[i]); } } RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected calling RequestExtendedLogin() locale=%s", locale); char *title = PL_strdup(entry->GetAuthentication()->GetTitle(locale)); RA::Debug("RA_Enroll_Processor::RequestUserId", "title=%s", title); char *description = PL_strdup(entry->GetAuthentication()->GetDescription(locale)); RA::Debug("RA_Enroll_Processor::RequestUserId", "description=%s", description); login = RequestExtendedLogin(session, 0 /* invalid_pw */, 0 /* blocked */, params, n, title, description); RA::Debug("RA_Enroll_Processor::RequestUserId", "Extended Login Request detected calling RequestExtendedLogin() login=%x", login); if (params != NULL) { for (int nn=0; nn < n; nn++) { if (params[nn] != NULL) { PL_strfree(params[nn]); params[nn] = NULL; } } free(params); params = NULL; } if (title != NULL) { PL_strfree(title); title = NULL; } if (description != NULL) { PL_strfree(description); description = NULL; } } else { login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */); } if (login == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "login not provided"); status = STATUS_ERROR_LOGIN; PR_snprintf(audit_msg, 512, "login not provided, status = STATUS_ERROR_LOGIN"); goto loser; } if( userid != NULL ) { PR_Free( (char *) userid ); userid = NULL; } userid = PL_strdup( login->GetUID() ); } if (extensions != NULL && extensions->GetValue("statusUpdate") != NULL) { StatusUpdate(session, 30 /* progress */, "PROGRESS_START_AUTHENTICATION"); } RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "userid obtained"); PR_snprintf(configname, 256, "cn=%s", cuid); rc = RA::ra_find_tus_token_entries(configname, maxReturns, &ldapResult, 0); if (rc == 0) { for (e = RA::ra_get_first_entry(ldapResult); e != NULL; e = RA::ra_get_next_entry(e)) { tokenOwner = RA::ra_get_attribute_values(e, "tokenUserID"); if ((tokenOwner != NULL) && (tokenOwner[0] != NULL) && (tokenOwner[0]->bv_val != NULL) && (strlen(tokenOwner[0]->bv_val) > 0) && (strcmp(userid, tokenOwner[0]->bv_val) != 0)) { status = STATUS_ERROR_NOT_TOKEN_OWNER; PR_snprintf(audit_msg, 512, "token owner mismatch, status = STATUS_ERROR_NOT_TOKEN_OWNER"); goto loser; } } } else { RA::Error("RA_Pin_Reset_Processor::Process", "Error in ldap connection with token database."); status = STATUS_ERROR_LDAP_CONN; PR_snprintf(audit_msg, 512, "Error in ldap connection with token database, status = STATUS_ERROR_LDAP_CONN"); goto loser; } PR_snprintf((char *)configname, 256, "%s.%s.auth.enable", OP_PREFIX, tokenType); if (RA::GetConfigStore()->GetConfigAsBool(configname, false)) { if (login == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "Login Request Disabled. Authentication failed."); status = STATUS_ERROR_LOGIN; PR_snprintf(audit_msg, 512, "Login Request Disabled. status = STATUS_ERROR_LOGIN"); goto loser; } PR_snprintf((char *)configname, 256, "%s.%s.auth.id", OP_PREFIX, tokenType); authid = RA::GetConfigStore()->GetConfigAsString(configname); if (authid == NULL) { status = STATUS_ERROR_LOGIN; PR_snprintf(audit_msg, 512, "authid is null, status = STATUS_ERROR_LOGIN"); goto loser; } AuthenticationEntry *auth = RA::GetAuth(authid); if(auth == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "Authentication manager is NULL . Authentication failed."); status = STATUS_ERROR_LOGIN; PR_snprintf(audit_msg, 512, "Authentication manager is NULL, status = STATUS_ERROR_LOGIN"); goto loser; } char *type = auth->GetType(); if (type == NULL) { status = STATUS_ERROR_LOGIN; RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "authentication is missing param type", "", tokenType); PR_snprintf(audit_msg, 512, "authentication is missing param type, status = STATUS_ERROR_LOGIN"); goto loser; } if (strcmp(type, "LDAP_Authentication") == 0) { RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "LDAP_Authentication is invoked."); int passwd_retries = auth->GetAuthentication()->GetNumOfRetries(); int retries = 0; authParams = new AuthParams(); authParams->SetUID(login->GetUID()); authParams->SetPassword(login->GetPassword()); rc = auth->GetAuthentication()->Authenticate(authParams); RA::Debug("RA_Pin_Reset_Processor::Process", "Authenticate returns: %d", rc); while ((rc == -2 || rc == -3) && (retries < passwd_retries)) { login = RequestLogin(session, 0 /* invalid_pw */, 0 /* blocked */); if (login == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "Login Request Disabled. Authentication failed."); status = STATUS_ERROR_LOGIN; PR_snprintf(audit_msg, 512, "Login Request Disabled, r=-2 or -3. status= STATUS_ERROR_LOGIN"); goto loser; } retries++; authParams->SetUID(login->GetUID()); authParams->SetPassword(login->GetPassword()); rc = auth->GetAuthentication()->Authenticate(authParams); } if (rc == -1) { RA::Error("RA_Pin_Reset_Processor::Process", "Authentication failed."); status = STATUS_ERROR_LDAP_CONN; RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication status = %d", status); PR_snprintf(audit_msg, 512, "authentication failed, rc=-1, status = STATUS_ERROR_LDAP_CONN"); goto loser; } if (rc == -2 || rc == -3) { RA::Error("RA_Pin_Reset_Processor::Process", "Authentication failed."); status = STATUS_ERROR_LOGIN; RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication status = %d", status); PR_snprintf(audit_msg, 512, "authentication failed, rc=-2 or rc=-3, status = STATUS_ERROR_LOGIN"); goto loser; } RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication successful."); } else { RA::Error("RA_Pin_Reset_Processor::Process", "No Authentication type was found."); status = STATUS_ERROR_LOGIN; RA::tdb_activity(session->GetRemoteIP(), cuid, "enrollment", "failure", "authentication error", "", tokenType); PR_snprintf(audit_msg, 512, "No Authentication type was found. status = STATUS_ERROR_LOGIN"); goto loser; } } else { RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "Authentication has been disabled."); } RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "authentication successful"); RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "SetupSecureChannel"); #if 0 if (RA::GetConfigStore()->GetConfigAsBool("tus.enable", 0)) { if (IsTokenDisabledByTus(channel)) { status = STATUS_ERROR_TOKEN_DISABLED; goto loser; } } #endif /* check if the user owns the token */ token_userid = RA::ra_get_token_userid(cuid); if (token_userid == NULL) { RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "No user owns the token '%s'", cuid); status = STATUS_ERROR_TOKEN_DISABLED; PR_snprintf(audit_msg, 512, "No user owns the token, status = STATUS_ERROR_TOKEN_DISABLED"); goto loser; } else { if (strcmp(token_userid, userid) != 0) { RA::Error(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "User does not own the token '%s'", cuid); status = STATUS_ERROR_TOKEN_DISABLED; PR_snprintf(audit_msg, 512, "User does not own the token. status = STATUS_ERROR_TOKEN_DISABLED"); goto loser; } } RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "login successful"); RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "ExternalAuthenticate"); rc = channel->ExternalAuthenticate(); if (rc == -1) { RA::Error("RA_Pin_Reset_Processor::Process", "External Authenticate failed."); status = STATUS_ERROR_CREATE_CARDMGR; RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "external authentication error", "", tokenType); PR_snprintf(audit_msg, 512, "External Authenticate failed, status = STATUS_ERROR_CREATE_CARDMGR"); goto loser; } RA::Debug(LL_PER_PDU, "RA_Pin_Reset_Processor::Process", "RequestNewPin"); PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.minLen", OP_PREFIX, tokenType); minlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 4); PR_snprintf((char *)configname, 256, "%s.%s.pinReset.pin.maxLen", OP_PREFIX, tokenType); maxlen = RA::GetConfigStore()->GetConfigAsUnsignedInt(configname, 10); new_pin = RequestNewPin(session, minlen, maxlen); if (new_pin == NULL) { RA::Error("RA_Pin_Reset_Processor::Process", "Set Pin failed."); status = STATUS_ERROR_MAC_RESET_PIN_PDU; RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "request new pin error", "", tokenType); PR_snprintf(audit_msg, 512, "RequestNewPin failed, status = STATUS_ERROR_MAC_RESET_PIN_PDU"); goto loser; } if (extensions != NULL && extensions->GetValue("statusUpdate") != NULL) { StatusUpdate(session, 70 /* progress */, "PROGRESS_PIN_RESET"); } rc = channel->ResetPin(0x0, new_pin); if (rc == -1) { status = STATUS_ERROR_MAC_RESET_PIN_PDU; RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "ereset pin error", "", tokenType); PR_snprintf(audit_msg, 512, "ResetPin failed, status = STATUS_ERROR_MAC_RESET_PIN_PDU"); goto loser; } rc = channel->Close(); if (rc == -1) { RA::Error("RA_Pin_Reset_Processor::Process", "Failed to close channel"); status = STATUS_ERROR_CONNECTION; RA::tdb_activity(session->GetRemoteIP(), cuid, "pin reset", "failure", "secure channel close error", "", tokenType); PR_snprintf(audit_msg, 512, "Failed to close channel, status = STATUS_ERROR_CONNECTION"); goto loser; } //Update the KeyInfo in case of successful key changeover if (key_change_over_success != 0) { RA::tdb_update( userid != NULL ? userid : (char *) "", cuid != NULL ? cuid : (char *) "" , final_applet_version != NULL ? (char *) final_applet_version : (char *) "" , keyVersion != NULL ? keyVersion : (char *) "","active", "", tokenType != NULL ? tokenType : (char *) ""); } RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "success", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "ResetPin successful"); if (extensions != NULL && extensions->GetValue("statusUpdate") != NULL) { StatusUpdate(session, 100 /* progress */, "PROGRESS_DONE"); } end = PR_IntervalNow(); rc = 1; if (RA::ra_is_token_present(cuid)) { /* * we want to have a tus policy to change PIN_RESET=YES * parameter to PIN_RESET=NO */ if (RA::ra_is_token_pin_resetable(cuid)) { policy = RA::ra_get_token_policy(cuid); RA::Error("RA_Pin_Reset_Processor::Process", "Policy %s is %s", cuid, policy); tmp_policy = PL_strstr(policy, "PIN_RESET=YES"); if (tmp_policy != NULL) { tmp_policy[10] = 'N'; tmp_policy[11] = 'O'; for (i = 12; tmp_policy[i] != '\0'; i++) tmp_policy[i] = tmp_policy[i+1]; rc = RA::ra_update_token_policy(cuid, policy); if (rc != 0) { RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "failure", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", "failed to reset token policy"); } } } } sprintf(activity_msg, "applet_version=%s tokenType=%s", (char *)final_applet_version, tokenType); RA::tdb_activity(session->GetRemoteIP(), (char *)cuid, "pin reset", "success", activity_msg, userid, tokenType); /* audit log for successful pin reset */ if (authid != NULL) { sprintf(activity_msg, "pin_reset processing completed, authid = %s", authid); } else { sprintf(activity_msg, "pin_reset processing completed"); } RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid, cuid, msn, "success", "pin_reset", final_applet_version, keyVersion!=NULL? keyVersion: "", activity_msg); loser: if (strlen(audit_msg) > 0) { RA::Audit(EV_PIN_RESET, AUDIT_MSG_PROC, userid != NULL ? userid : "", cuid != NULL ? cuid : "", msn != NULL ? msn : "", "failure", "pin_reset", final_applet_version != NULL ? final_applet_version : "", keyVersion != NULL? keyVersion : "", audit_msg); if ((cuid != NULL) && (tokenType != NULL)) { RA::tdb_activity(session->GetRemoteIP(), cuid, "pin_reset", "failure", audit_msg, userid != NULL ? userid : "", tokenType); } } if (curKeyInfoStr != NULL) { PR_Free( (char *) curKeyInfoStr); curKeyInfoStr = NULL; } if (newVersionStr != NULL) { PR_Free( (char *) newVersionStr); newVersionStr = NULL; } if( token_status != NULL ) { delete token_status; token_status = NULL; } if( CardManagerAID != NULL ) { delete CardManagerAID; CardManagerAID = NULL; } if( NetKeyAID != NULL ) { delete NetKeyAID; NetKeyAID = NULL; } if( login != NULL ) { delete login; login = NULL; } if( new_pin != NULL ) { PL_strfree( new_pin ); new_pin = NULL; } if( channel != NULL ) { delete channel; channel = NULL; } if( cuid != NULL ) { PR_Free( (char *) cuid ); cuid = NULL; } if( msn != NULL ) { PR_Free( (char *) msn ); msn = NULL; } if( buildID != NULL ) { delete buildID; buildID = NULL; } if( appletVersion != NULL ) { PR_Free( (char *) appletVersion ); appletVersion = NULL; } if( final_applet_version != NULL ) { PR_Free( (char *) final_applet_version ); final_applet_version = NULL; } if( keyVersion != NULL ) { PR_Free( (char *) keyVersion ); keyVersion = NULL; } if( userid != NULL ) { PR_Free( (char *) userid ); userid = NULL; } if( authParams != NULL ) { delete authParams; authParams = NULL; } if( cplc_data != NULL ) { delete cplc_data; cplc_data = NULL; } if (tokenOwner != NULL) { ldap_value_free_len(tokenOwner); tokenOwner = NULL; } if (ldapResult != NULL) { ldap_msgfree(ldapResult); ldapResult = NULL; } #ifdef MEM_PROFILING MEM_dump_unfree(); #endif return status; } /* Process */