예제 #1
0
void 
perform_zone_export(int sockfd, engineconfig_type *config, const char *zone)
{
	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_AND_RETURN("transaction not started");
		
		{	OrmResultRef rows;
			ods::keystate::KeyStateExport kexport;
			
			std::string qzone;
			if (!OrmQuoteStringValue(conn, std::string(zone), qzone))
				ODS_LOG_AND_RETURN("quoting string value failed");
			
			if (!OrmMessageEnumWhere(conn,kexport.zone().descriptor(),
									 rows,"name = %s",qzone.c_str()))
				ODS_LOG_AND_RETURN("message enumeration failed");

			for (bool next=OrmFirst(rows); next; next=OrmNext(rows)) {
				
				if (!OrmGetMessage(rows, *kexport.mutable_zone(), true))
					ODS_LOG_AND_CONTINUE("reading zone from database failed");

				if (!write_pb_message_to_xml_fd(kexport.mutable_zone(),sockfd))
					ODS_LOG_AND_CONTINUE("writing message to xml file failed");
			}
		}
    }
}
void 
perform_keystate_ds_retract(int sockfd, engineconfig_type *config,
							const char *zone, const char *id, int bauto)
{
	GOOGLE_PROTOBUF_VERIFY_VERSION;
	OrmConnRef conn;
	if (ods_orm_connect(sockfd, config, conn)) {
		// Evaluate parameters and retract keys from the parent when instructed to.
		if (zone || id || bauto)
			retract_keys(conn,sockfd,zone,id,config->datastore,
						 config->delegation_signer_retract_command);
		else
			list_keys_retract(conn,sockfd,config->datastore);
	}
}
예제 #3
0
void 
perform_update_hsmkeys(int sockfd, engineconfig_type *config, int bManual)
{
	// check that we are using a compatible protobuf version.
	GOOGLE_PROTOBUF_VERIFY_VERSION;
	
	OrmConnRef conn;
	if (!ods_orm_connect(sockfd, config, conn))
		return; // errors have already been reported.
	
	// Go through all the keys in HSMs and import them if they are 
	// not already present
	if (bManual) {
		ods_printf(sockfd, "Database set to: %s\n", config->datastore);
		// DEPRECATED, key state import should selectively import keys.
		import_all_keys_from_all_hsms(sockfd,conn);
	}
}
예제 #4
0
void 
perform_keystate_export(int sockfd, engineconfig_type *config, const char *zone,
                        int bds)
{
	#define LOG_AND_RETURN(errmsg) do { ods_log_error_and_printf(\
		sockfd,module_str,errmsg); return; } while (0)
	#define LOG_AND_RETURN_1(errmsg,param) do { ods_log_error_and_printf(\
		sockfd,module_str,errmsg,param); return; } while (0)

	GOOGLE_PROTOBUF_VERIFY_VERSION;
    
	OrmConnRef conn;
	if (!ods_orm_connect(sockfd, config, conn))
		return; // error already reported.
	
	{	OrmTransactionRW transaction(conn);
		if (!transaction.started())
			LOG_AND_RETURN("transaction not started");

		std::string qzone;
		if (!OrmQuoteStringValue(conn, std::string(zone), qzone))
			LOG_AND_RETURN("quoting string value failed");
		
		{	OrmResultRef rows;
			::ods::keystate::EnforcerZone enfzone;
			if (!OrmMessageEnumWhere(conn,enfzone.descriptor(),
									 rows,"name = %s",qzone.c_str()))
				LOG_AND_RETURN("zone enumeration failed");
			
			if (!OrmFirst(rows)) {
				ods_printf(sockfd,"zone %s not found\n",zone);
				return;
			}
			
			OrmContextRef context;
			if (!OrmGetMessage(rows, enfzone, /*zones + keys*/true, context))
				LOG_AND_RETURN("retrieving zone from database failed");
			
			// we no longer need the query result, so release it.
			rows.release();

			// Retrieve the dnskey ttl from the policy associated with the zone.
			::ods::kasp::Policy policy;
			if (!load_kasp_policy(conn, enfzone.policy(), policy))
				LOG_AND_RETURN_1("policy %s not found",enfzone.policy().c_str());
			uint32_t dnskey_ttl = policy.keys().ttl();

			bool bSubmitChanged = false;
			bool bRetractChanged = false;
			bool bKeytagChanged = false;
			
			for (int k=0; k<enfzone.keys_size(); ++k) {
				const ::ods::keystate::KeyData &key = enfzone.keys(k);
				if (key.role()==::ods::keystate::ZSK)
					continue;
				
				if (key.ds_at_parent()!=::ods::keystate::submit
					&& key.ds_at_parent()!=::ods::keystate::submitted
					&& key.ds_at_parent()!=::ods::keystate::retract
					&& key.ds_at_parent()!=::ods::keystate::retracted
					)
					continue;
				
				std::string dnskey;
				uint16_t keytag = dnskey_from_id(dnskey,key.locator().c_str(),
												 key.role(),
												 enfzone.name().c_str(),
												 key.algorithm(),bds,
												 dnskey_ttl);
				if (keytag) {
					ods_writen(sockfd, dnskey.c_str(), dnskey.size());
					bSubmitChanged = key.ds_at_parent()==::ods::keystate::submit;
					bRetractChanged = key.ds_at_parent()==::ods::keystate::retract;
					bKeytagChanged = key.keytag()!=keytag;
					if (bSubmitChanged) {
						::ods::keystate::KeyData *kd = enfzone.mutable_keys(k);
						kd->set_ds_at_parent(::ods::keystate::submitted);
					}
					if (bRetractChanged) {
						::ods::keystate::KeyData *kd = enfzone.mutable_keys(k);
						kd->set_ds_at_parent(::ods::keystate::retracted);
					}
					if (bKeytagChanged) {
						::ods::keystate::KeyData *kd = enfzone.mutable_keys(k);
						kd->set_keytag(keytag);
					}
				} else
					LOG_AND_RETURN_1("unable to find key with id %s",
									 key.locator().c_str());
			}
    
			if (bSubmitChanged || bRetractChanged || bKeytagChanged) {
				// Update the zone recursively in the database as keystates
				// have been changed because of the export
				
				if (!OrmMessageUpdate(context))
					LOG_AND_RETURN("updating zone in the database failed");
				
				
				if (!transaction.commit())
					LOG_AND_RETURN("committing zone to the database failed");
			}
		}
	}
}
예제 #5
0
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);
			}
		}
	}


}
예제 #6
0
void 
perform_update_kasp(int sockfd, engineconfig_type *config)
{
	GOOGLE_PROTOBUF_VERIFY_VERSION;
    
    std::auto_ptr< ::ods::kasp::KaspDocument > kaspDoc;
	if (!load_kasp_xml(sockfd, config->policy_filename, kaspDoc))
		return; // errors have already been reported.
	
	OrmConnRef conn;
	if (!ods_orm_connect(sockfd, config, conn))
		return;  // errors have already been reported.

	//TODO: SPEED: We should create an index on the Policy.name column
	
    // Go through the list of policies from the kasp.xml file to determine
	// if we need to insert new policies to the policies table.
    for (int i=0; i<kaspDoc->kasp().policies_size(); ++i) {
        const ::ods::kasp::Policy &policy = kaspDoc->kasp().policies(i);
		
		{	OrmTransactionRW transaction(conn);
			if (!transaction.started()) {
				ods_log_error_and_printf(sockfd, module_str,
										 "starting a database transaction for "
										 "updating a policy failed");
				return;
			}
			
			std::string qpolicy;
			if (!OrmQuoteStringValue(conn, policy.name(), qpolicy)) {
				ods_log_error_and_printf(sockfd, module_str,
										 "quoting a string failed");
				return;
			}
			
			// delete the existing policy from the database
			if (!OrmMessageDeleteWhere(conn, policy.descriptor(),
									   "name=%s",qpolicy.c_str())) {
				ods_log_error_and_printf(sockfd, module_str,
										 "failed to delete policy with "
										 "name %s",policy.name().c_str());
				return;
			}
				
			// insert the policy we read from the kasp.xml file.
			pb::uint64 policyid;
			if (!OrmMessageInsert(conn, policy, policyid)) {
				ods_log_error_and_printf(sockfd, module_str,
							"inserting policy into the database failed");
				return;
			}
			
			// commit the update policy to the database.
			if (!transaction.commit()) {
				ods_log_error_and_printf(sockfd, module_str,
										 "committing policy to the database failed");
				return;
			}
		}
    }
}
예제 #7
0
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()
							   );
				}
			}
		}
    }
}