static void list_keys_retract(OrmConn conn, int sockfd, const char *datastore) { #define LOG_AND_RETURN(errmsg)\ do{ods_log_error_and_printf(sockfd,module_str,errmsg);return;}while(0) // List the keys with retract flags. ods_printf(sockfd, "Database set to: %s\n" "Retract Keys:\n" "Zone: " "Key role: " "Id: " "\n" ,datastore ); OrmTransaction transaction(conn); if (!transaction.started()) LOG_AND_RETURN("transaction not started"); { OrmResultRef rows; ::ods::keystate::EnforcerZone enfzone; if (!OrmMessageEnum(conn,enfzone.descriptor(),rows)) LOG_AND_RETURN("zone enumeration failed"); for (bool next=OrmFirst(rows); next; next=OrmNext(rows)) { if (!OrmGetMessage(rows, enfzone, /*zones + keys*/true)) LOG_AND_RETURN("retrieving zone from database failed"); for (int k=0; k<enfzone.keys_size(); ++k) { const ::ods::keystate::KeyData &key = enfzone.keys(k); // Don't suggest ZSKs can be retracted, don't show them if (key.role() == ::ods::keystate::ZSK) continue; // Only show keys that have the retract flag set. if (key.ds_at_parent()!=::ods::keystate::retract) continue; std::string keyrole = keyrole_Name(key.role()); ods_printf(sockfd, "%-31s %-13s %-40s\n", enfzone.name().c_str(), keyrole.c_str(), key.locator().c_str() ); } } } #undef LOG_AND_RETURN }
bool HsmKeyFactoryPB::GetHsmKeyByLocator(const std::string loc, HsmKey **ppKey) { // First try to match one of the existing HsmKeyPB objects std::map<std::string,HsmKeyPB>::iterator lk = _keys.find(loc); if (lk != _keys.end()) { *ppKey = &lk->second; return true; } // Now enumerate keys in the document try to find a key that matches the // parameters exactly and is not yet present in the _keys vector field. OrmResultRef rows; if (OrmMessageEnum(_conn, ::ods::hsmkey::HsmKey::descriptor(), rows)) { ::ods::hsmkey::HsmKey *pbkey = NULL; for (bool next=OrmFirst(rows); next; next=OrmNext(rows)) { if (!pbkey) pbkey = new ::ods::hsmkey::HsmKey; if (OrmGetMessage(rows, *pbkey, true)) { if (pbkey->locator() == loc) { std::pair<std::map<std::string,HsmKeyPB>::iterator,bool> ret; ret = _keys.insert( std::pair<std::string,HsmKeyPB>(loc,HsmKeyPB(pbkey)) ); pbkey = NULL; *ppKey = &ret.first->second; return true; } } } if (pbkey) delete pbkey; } return false; }
bool HsmKeyFactoryPB::UseSharedKey(int bits, const std::string &repository, const std::string &policy, int algorithm, KeyRole role, const std::string &zone, HsmKey **ppKey) { // First try to match one of the existing HsmKeyPB objects std::map<std::string,HsmKeyPB>::iterator k; for (k = _keys.begin(); k != _keys.end(); ++k) { if (k->second.bits() == bits && k->second.policy() == policy && k->second.algorithm() == algorithm && k->second.keyRole() == role && !k->second.usedByZone(zone) && k->second.candidateForSharing() ) { *ppKey = &k->second; (*ppKey)->setUsedByZone(zone,true); return true; } } #if 0 // All the database access has to be done within a single transaction OrmTransactionRW trans(_conn); #endif // Now enumerate keys in the document try to find a key that matches the // parameters exactly and is not yet present in the _keys vector field. OrmResultRef rows; if (OrmMessageEnum(_conn, ::ods::hsmkey::HsmKey::descriptor(), rows)) { ::ods::hsmkey::HsmKey *pbkey = NULL; for (bool next=OrmFirst(rows); next; next=OrmNext(rows)) { if (!pbkey) pbkey = new ::ods::hsmkey::HsmKey; OrmContextRef context; if (OrmGetMessage(rows, *pbkey, true, context)) { if (pbkey->has_inception() && pbkey->bits() == bits && pbkey->repository() == repository && pbkey->policy() == policy && pbkey->algorithm() == algorithm && pbkey->role() == (::ods::hsmkey::keyrole)role ) { pbkey->set_inception(time_now()); HsmKeyPB pbkey_ref(pbkey); // Fixate unset attributes that returned their default value. // Otherwise when we list the keys those values will show // up as 'not set' if (!pbkey->has_policy()) pbkey_ref.setPolicy(policy); if (!pbkey->has_algorithm()) pbkey_ref.setAlgorithm(algorithm); if (!pbkey->has_role()) pbkey_ref.setKeyRole(role); pbkey = NULL; // We have modified the key and need to update it. if (OrmMessageUpdate(context)) { // we won't be needing the result anymore, so release it rows.release(); #if 0 // now more active queries, so commit should work. if (trans.commit()) { #endif std::pair<std::map<std::string,HsmKeyPB>::iterator,bool> ret; ret = _keys.insert(std::pair<std::string,HsmKeyPB>( pbkey_ref.locator(),pbkey_ref)); *ppKey = &ret.first->second; (*ppKey)->setUsedByZone(zone,true); return true; #if 0 } #endif } } } } if (pbkey) delete pbkey; rows.release(); } #if 0 // transaction rolback is default, but we make it explicit here. trans.rollback(); #endif return false; }
static void retract_keys(OrmConn conn, int sockfd, const char *zone, const char *id, const char *datastore, const char *ds_retract_command) { #define LOG_AND_RETURN(errmsg)\ do{ods_log_error_and_printf(sockfd,module_str,errmsg);return;}while(0) #define LOG_AND_RETURN_1(errmsg,p)\ do{ods_log_error_and_printf(sockfd,module_str,errmsg,p);return;}while(0) OrmTransactionRW transaction(conn); if (!transaction.started()) LOG_AND_RETURN("transaction not started"); { OrmResultRef rows; ::ods::keystate::EnforcerZone enfzone; if (zone) { std::string qzone; if (!OrmQuoteStringValue(conn, std::string(zone), qzone)) LOG_AND_RETURN("quoting string value failed"); if (!OrmMessageEnumWhere(conn,enfzone.descriptor(), rows,"name = %s",qzone.c_str())) LOG_AND_RETURN("zone enumeration failed"); } else { if (!OrmMessageEnum(conn,enfzone.descriptor(),rows)) LOG_AND_RETURN("zone enumeration failed"); } bool bZonesModified = false; if (!OrmFirst(rows)) { if (zone) LOG_AND_RETURN_1("zone %s not found",zone); } else { for (bool next=true; next; next=OrmNext(rows)) { OrmContextRef context; if (!OrmGetMessage(rows, enfzone, /*zones + keys*/true, context)) LOG_AND_RETURN("retrieving zone from database failed"); // Try to change the state of a specific 'retract' key to 'retracted'. bool bKeyModified = false; for (int k=0; k<enfzone.keys_size(); ++k) { const ::ods::keystate::KeyData &key = enfzone.keys(k); // Don't retract ZSKs from the parent. if (key.role()==::ods::keystate::ZSK) continue; // Only retract KSKs that have the retract flag set. if (key.ds_at_parent()!=::ods::keystate::retract) continue; if (id) { // --id <id> // Force retract key to the parent for specific key id. if (key.locator()==id) { // retract key with this id from the parent if (retract_dnskey_by_id(sockfd,ds_retract_command, key.locator().c_str(), key.role(), enfzone.name().c_str(), key.algorithm())) { ::ods::keystate::KeyData *kd = enfzone.mutable_keys(k); kd->set_ds_at_parent(::ods::keystate::retracted); bKeyModified = true; } } } else { if (zone) { // --zone <zone> // Force retract key from the parent for specific zone. if (enfzone.name()==zone) { // retract key for this zone from the parent if (retract_dnskey_by_id(sockfd,ds_retract_command, key.locator().c_str(), key.role(), enfzone.name().c_str(), key.algorithm())) { ::ods::keystate::KeyData *kd = enfzone.mutable_keys(k); kd->set_ds_at_parent(::ods::keystate::retracted); bKeyModified = true; } } } else { // --auto // Retract all keys from the parent that have // the retract flag set. if (retract_dnskey_by_id(sockfd,ds_retract_command, key.locator().c_str(), key.role(), enfzone.name().c_str(), key.algorithm())) { ::ods::keystate::KeyData *kd = enfzone.mutable_keys(k); kd->set_ds_at_parent(::ods::keystate::retracted); bKeyModified = true; } } } } if (bKeyModified) { if (!OrmMessageUpdate(context)) LOG_AND_RETURN_1("failed to update zone %s in the database", enfzone.name().c_str()); bZonesModified = true; } } // we no longer need the query result, so release it. rows.release(); } // Report back the status of the operation. if (bZonesModified) { // Commit updated records to the database. if (!transaction.commit()) LOG_AND_RETURN_1("unable to commit updated zone %s to the database",zone); ods_log_debug("[%s] key states have been updated",module_str); ods_printf(sockfd,"update of key states completed.\n"); } else { ods_log_debug("[%s] key states are unchanged",module_str); if (id) ods_printf(sockfd, "No key state changes for id \"%s\"\n", id); else if (zone) ods_printf(sockfd, "No key state changes for zone \"%s\"\n", zone); else ods_printf(sockfd,"key states are unchanged\n"); } } #undef LOG_AND_RETURN #undef LOG_AND_RETURN_1 }
void perform_zone_del(int sockfd, engineconfig_type *config, const char *zone, int need_write_xml, bool quiet) { GOOGLE_PROTOBUF_VERIFY_VERSION; OrmConnRef conn; if (!ods_orm_connect(sockfd, config, conn)) return; // error already reported. std::string qzone; bool is_del_succeed = false; if (strlen(zone) > 0) { if (!OrmQuoteStringValue(conn, std::string(zone), qzone)) { const char *emsg = "quoting zone value failed"; ods_log_error_and_printf(sockfd,module_str,emsg); return; } } { OrmTransactionRW transaction(conn); if (!transaction.started()) { const char *emsg = "could not start database transaction"; ods_log_error_and_printf(sockfd,module_str,emsg); return; } if (qzone.empty()) { OrmResultRef rows; ::ods::keystate::EnforcerZone enfzone; std::vector<std::string> del_zones; bool ok = OrmMessageEnum(conn, enfzone.descriptor(), rows); if (!ok) { transaction.rollback(); ods_log_error("[%s] enum enforcer zone failed", module_str); return; } for (bool next=OrmFirst(rows); next; next = OrmNext(rows)) { OrmContextRef context; if (!OrmGetMessage(rows, enfzone, true, context)) { rows.release(); transaction.rollback(); ods_log_error("[%s] retrieving zone from database failed"); return; } del_zones.push_back(enfzone.name()); } rows.release(); for (std::vector<std::string>::iterator it = del_zones.begin(); it != del_zones.end(); ++it) { std::string del_zone; if (!OrmQuoteStringValue(conn, std::string(*it), del_zone)) { transaction.rollback(); const char *emsg = "quoting zone value failed"; ods_log_error_and_printf(sockfd,module_str,emsg); return; } if (!OrmMessageDeleteWhere(conn, ::ods::keystate::EnforcerZone::descriptor(), "name = %s", del_zone.c_str())) { transaction.rollback(); const char *emsg = "unable to delete zone %s"; ods_log_error_and_printf(sockfd,module_str,emsg, it->c_str()); return; } is_del_succeed = true; } } else { //find the zone OrmResultRef rows; if (!OrmMessageEnumWhere(conn, ::ods::keystate::EnforcerZone::descriptor(), rows, "name = %s", qzone.c_str())) { transaction.rollback(); ods_log_error_and_printf(sockfd, module_str, "unable to find zone %s", qzone.c_str()); return; } if (!OrmFirst(rows)) { rows.release(); transaction.rollback(); ods_log_error_and_printf(sockfd, module_str, "Couldn't find zone %s", qzone.c_str()); return; } rows.release(); if (!OrmMessageDeleteWhere(conn, ::ods::keystate::EnforcerZone::descriptor(), "name = %s", qzone.c_str())) { transaction.rollback(); const char *emsg = "unable to delete zone %s"; ods_log_error_and_printf(sockfd,module_str,emsg,qzone.c_str()); return; } is_del_succeed = true; } if (!transaction.commit()) { const char *emsg = "committing delete of zone %s to database failed"; ods_log_error_and_printf(sockfd,module_str,emsg,qzone.c_str()); return; } } // Now lets write out the required files - the internal list and optionally the zonelist.xml // Note at the moment we re-export the whole file in zonelist.xml format here but this should be optimised.... if (is_del_succeed) { if (!perform_write_signzone_file(sockfd, config)) { ods_log_error_and_printf(sockfd, module_str, "failed to write internal zonelist"); } if (need_write_xml) { if (!perform_zonelist_export_to_file(config->zonelist_filename,config)) { ods_log_error_and_printf(sockfd, module_str, "failed to write zonelist.xml"); } if (!quiet) { if (qzone.empty()) { ods_printf(sockfd, "Deleted all zones in database and zonelist.xml updated.\n"); } else { ods_printf(sockfd, "Deleted zone: %s in database and zonelist.xml updated.\n", zone); } } } else if (!quiet) { if (qzone.empty()) { ods_printf(sockfd, "Deleted all zones in database only. Use the --xml flag or run \"ods-enforcer zonelist export\" if an update of zonelist.xml is required.\n", zone); } else { ods_printf(sockfd, "Deleted zone: %s in database only. Use the --xml flag or run \"ods-enforcer zonelist export\" if an update of zonelist.xml is required.\n", zone); } } } }
void perform_keystate_list(int sockfd, engineconfig_type *config, int bverbose) { GOOGLE_PROTOBUF_VERIFY_VERSION; OrmConnRef conn; if (!ods_orm_connect(sockfd, config, conn)) return; // error already reported. { OrmTransaction transaction(conn); if (!transaction.started()) { ods_log_error("[%s] Could not start database transaction", module_str); ods_printf(sockfd, "error: Could not start database transaction\n"); return; } ::ods::keystate::EnforcerZone zone; { OrmResultRef rows; if (!OrmMessageEnum(conn, zone.descriptor(),rows)) { ods_log_error("[%s] error enumerating zones", module_str); ods_printf(sockfd, "error enumerating zones\n"); return; } ods_printf(sockfd, "Database set to: %s\n" "Keys:\n" "Zone: " "Key role: " "DS: " "DNSKEY: " "RRSIGDNSKEY: " "RRSIG: " "Pub: " "Act: " "Id:" "\n" ,config->datastore ); for (bool next=OrmFirst(rows); next; next=OrmNext(rows)) { if (!OrmGetMessage(rows, zone, true)) { ods_log_error("[%s] error reading zone", module_str); ods_printf(sockfd, "error reading zone\n"); return; } for (int k=0; k<zone.keys_size(); ++k) { const ::ods::keystate::KeyData &key = zone.keys(k); std::string keyrole = keyrole_Name(key.role()); std::string ds_rrstate = rrstate_Name(key.ds().state()); std::string dnskey_rrstate = rrstate_Name(key.dnskey().state()); std::string rrsigdnskey_rrstate = rrstate_Name(key.rrsigdnskey().state()); std::string rrsig_rrstate = rrstate_Name(key.rrsig().state()); ods_printf(sockfd, "%-31s %-13s %-12s %-12s %-12s %-12s %d %4d %s\n", zone.name().c_str(), keyrole.c_str(), ds_rrstate.c_str(), dnskey_rrstate.c_str(), rrsigdnskey_rrstate.c_str(), rrsig_rrstate.c_str(), key.publish(), key.active_ksk()||key.active_zsk(), key.locator().c_str() ); } } } } }