#include "pdns/arguments.hh"
#include <boost/algorithm/string.hpp>
#include <sstream>
+#include <boost/foreach.hpp>
using namespace boost;
void GSQLBackend::setNotified(uint32_t domain_id, uint32_t serial)
d_beforeOrderQuery = getArg("get-order-before-query");
d_afterOrderQuery = getArg("get-order-after-query");
d_setOrderAuthQuery = getArg("set-order-and-auth-query");
+
+ d_AddDomainKeyQuery = "insert into cryptokeys (domain_id, flags, active, content) select id, %d, %d, '%s' from domains where name='%s'";
+ d_ListDomainKeysQuery = "select cryptokeys.id, flags, active, content from domains, cryptokeys where domain_id=domains.id and name='%s'";
+
+ d_GetDomainMetadataQuery = "select content from domains, domainmetadata where domain_id=domains.id and name='%s' and domainmetadata.kind='%s'";
+ d_SetDomainMetadataQuery = "insert into domainmetadata (domain_id, kind, content) select id, '%s', '%s' from domains where name='%s'";
}
bool GSQLBackend::updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth)
return true;
}
+int GSQLBackend::addDomainKey(const string& name, const KeyData& key)
+{
+ char output[16384];
+ snprintf(output,sizeof(output)-1,d_AddDomainKeyQuery.c_str(),
+ key.flags, (int)key.active, sqlEscape(key.content).c_str(), sqlEscape(name).c_str());
+
+ try {
+ d_db->doCommand(output);
+ }
+ catch (SSqlException &e) {
+ throw AhuException("GSQLBackend unable to store key: "+e.txtReason());
+ }
+ return 1; // XXX FIXME, no idea how to get the id
+}
+
+bool GSQLBackend::getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys)
+{
+ char output[1024];
+ snprintf(output,sizeof(output)-1,d_ListDomainKeysQuery.c_str(), sqlEscape(name).c_str());
+
+ try {
+ d_db->doQuery(output);
+ }
+ catch (SSqlException &e) {
+ throw AhuException("GSQLBackend unable to list keys: "+e.txtReason());
+ }
+
+ SSql::row_t row;
+ // "select id, kind, active, content from domains, cryptokeys where domain_id=domains.id and name='%s'";
+ KeyData kd;
+ while(d_db->getRow(row)) {
+ //~ BOOST_FOREACH(const std::string& val, row) {
+ //~ cerr<<"'"<<val<<"'"<<endl;
+ //~ }
+ kd.id = atoi(row[0].c_str());
+ kd.flags = atoi(row[1].c_str());
+ kd.active = atoi(row[2].c_str());
+ kd.content = row[3];
+ keys.push_back(kd);
+ }
+
+ return true;
+}
+
+bool GSQLBackend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
+{
+ char output[1024];
+ snprintf(output,sizeof(output)-1,d_GetDomainMetadataQuery.c_str(), sqlEscape(name).c_str(), sqlEscape(kind).c_str());
+
+ try {
+ d_db->doQuery(output);
+ }
+ catch (SSqlException &e) {
+ throw AhuException("GSQLBackend unable to list keys: "+e.txtReason());
+ }
+
+ SSql::row_t row;
+ // "select id, kind, active, content from domains, cryptokeys where domain_id=domains.id and name='%s'";
+ KeyData kd;
+ while(d_db->getRow(row)) {
+ meta.push_back(row[0]);
+ }
+ return true;
+}
+
+bool GSQLBackend::setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta)
+{
+ char output[16384];
+ snprintf(output,sizeof(output)-1,d_SetDomainMetadataQuery.c_str(),
+ sqlEscape(kind).c_str(), sqlEscape(*meta.begin()).c_str(), sqlEscape(name).c_str());
+
+ try {
+ d_db->doCommand(output);
+ }
+ catch (SSqlException &e) {
+ throw AhuException("GSQLBackend unable to store metadata key: "+e.txtReason());
+ }
+ return true;
+}
+
void GSQLBackend::lookup(const QType &qtype,const string &qname, DNSPacket *pkt_p, int domain_id)
{
bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth);
virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth);
-
+ int addDomainKey(const string& name, const KeyData& key);
+ bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
+ bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
+ bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
private:
string d_qname;
QType d_qtype;
string d_afterOrderQuery;
string d_setOrderAuthQuery;
+ string d_AddDomainKeyQuery;
+ string d_ListDomainKeysQuery;
+ string d_GetDomainMetadataQuery;
+ string d_SetDomainMetadataQuery;
protected:
bool d_dnssecQueries;
};
--- /dev/null
+#include "dnsseckeeper.hh"
+#include "dnssecinfra.hh"
+#include "ueberbackend.hh"
+#include "statbag.hh"
+#include <iostream>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/foreach.hpp>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fstream>
+#include <boost/algorithm/string.hpp>
+#include <boost/format.hpp>
+#include <boost/assign/std/vector.hpp> // for 'operator+=()'
+#include <boost/assign/list_inserter.hpp>
+using namespace boost::assign;
+namespace fs = boost::filesystem;
+
+using namespace std;
+using namespace boost;
+
+bool DNSSECKeeper::haveActiveKSKFor(const std::string& zone, DNSSECPrivateKey* dpk)
+{
+ keyset_t keys = getKeys(zone, true);
+ // need to get an *active* one!
+ //cerr<<__FUNCTION__<<"Got "<<keys.size()<<" keys"<<endl;
+ if(dpk && !keys.empty()) {
+ *dpk = keys.begin()->first;
+ }
+ return !keys.empty();
+}
+
+
+void DNSSECKeeper::addKey(const std::string& name, bool keyOrZone, int algorithm, int bits, bool active)
+{
+ if(!bits)
+ bits = keyOrZone ? 2048 : 1024;
+ DNSSECPrivateKey dpk;
+ dpk.d_key.create(bits);
+
+ DNSBackend::KeyData kd;
+ kd.flags = 256 + keyOrZone;
+ kd.active = active;
+ kd.content = dpk.d_key.convertToISC(algorithm);
+
+ // now store it
+ UeberBackend db;
+ db.addDomainKey(name, kd);
+}
+
+
+static bool keyCompareByKindAndID(const DNSSECKeeper::keyset_t::value_type& a, const DNSSECKeeper::keyset_t::value_type& b)
+{
+ return make_pair(!a.second.keyOrZone, a.second.id) <
+ make_pair(!b.second.keyOrZone, b.second.id);
+}
+
+DNSSECPrivateKey DNSSECKeeper::getKeyById(const std::string& zname, unsigned int id)
+{
+ UeberBackend db;
+ vector<DNSBackend::KeyData> keys;
+ db.getDomainKeys(zname, 0, keys);
+ BOOST_FOREACH(const DNSBackend::KeyData& kd, keys) {
+ if(kd.id != id)
+ continue;
+
+ DNSSECPrivateKey dpk;
+
+ getRSAKeyFromISCString(&dpk.d_key.getContext(), kd.content);
+ dpk.d_flags = kd.flags;
+ dpk.d_algorithm = 5 + 2*getNSEC3PARAM(zname);
+
+ KeyMetaData kmd;
+
+ kmd.active = kd.active;
+ kmd.keyOrZone = (kd.flags == 257);
+ kmd.id = kd.id;
+
+ return dpk;
+ }
+ throw runtime_error("Can't find a key with id "+lexical_cast<string>(id)+" for zone '"+zname+"'");
+
+
+}
+
+
+void DNSSECKeeper::removeKey(const std::string& zname, unsigned int id)
+{
+ // XXX
+}
+
+void DNSSECKeeper::deactivateKey(const std::string& zname, unsigned int id)
+{
+ // XX
+}
+
+void DNSSECKeeper::activateKey(const std::string& zname, unsigned int id)
+{
+ // XXX
+}
+
+bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p)
+{
+ UeberBackend db;
+ vector<string> meta;
+ db.getDomainMetadata(zname, "NSEC3PARAM", meta);
+
+ if(meta.empty())
+ return false;
+
+ if(ns3p) {
+ string descr = *meta.begin();
+ reportAllTypes();
+ NSEC3PARAMRecordContent* tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, descr));
+ if(!tmp) {
+ cerr<<"descr: '"<<descr<<"'\n";
+ return false;
+ }
+ *ns3p = *tmp;
+ delete tmp;
+ }
+ return true;
+}
+
+void DNSSECKeeper::setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& ns3p)
+{
+ string descr = ns3p.getZoneRepresentation();
+ vector<string> meta;
+ meta.push_back(descr);
+ UeberBackend db;
+ db.setDomainMetadata(zname, "NSEC3PARAM", meta);
+
+ // XXX do db
+}
+
+void DNSSECKeeper::unsetNSEC3PARAM(const std::string& zname)
+{
+ // XXX do db
+}
+
+
+DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const std::string& zone, boost::tribool allOrKeyOrZone)
+{
+ keyset_t keyset;
+ UeberBackend db;
+ vector<UeberBackend::KeyData> dbkeyset;
+
+ db.getDomainKeys(zone, 0, dbkeyset);
+ // do db thing
+ //cerr<<"Here: received " <<dbkeyset.size()<<" keys"<<endl;
+ BOOST_FOREACH(UeberBackend::KeyData& kd, dbkeyset)
+ {
+ DNSSECPrivateKey dpk;
+
+ getRSAKeyFromISCString(&dpk.d_key.getContext(), kd.content);
+ dpk.d_flags = kd.flags;
+ dpk.d_algorithm = 5 + 2*getNSEC3PARAM(zone);
+
+ KeyMetaData kmd;
+
+ kmd.active = kd.active;
+ kmd.keyOrZone = (kd.flags == 257);
+ kmd.id = kd.id;
+
+ if(boost::indeterminate(allOrKeyOrZone) || allOrKeyOrZone == kmd.keyOrZone)
+ keyset.push_back(make_pair(dpk, kmd));
+ }
+ sort(keyset.begin(), keyset.end(), keyCompareByKindAndID);
+ return keyset;
+}
+
+void DNSSECKeeper::secureZone(const std::string& name, int algorithm)
+{
+ addKey(name, true, algorithm);
+}
+
+
#include <iostream>
#include <sstream>
#include <functional>
+#include <boost/foreach.hpp>
#include "dns.hh"
#include "arguments.hh"
return false;
}
+int UeberBackend::addDomainKey(const string& name, const KeyData& key)
+{
+ BOOST_FOREACH(DNSBackend* db, backends) {
+ if(db->addDomainKey(name, key) >= 0)
+ return true;
+ }
+ return false;
+}
+bool UeberBackend::getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys)
+{
+ BOOST_FOREACH(DNSBackend* db, backends) {
+ if(db->getDomainKeys(name, kind, keys))
+ return true;
+ }
+ return false;
+}
+
+bool UeberBackend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
+{
+ BOOST_FOREACH(DNSBackend* db, backends) {
+ if(db->getDomainMetadata(name, kind, meta))
+ return true;
+ }
+ return false;
+}
+
+bool UeberBackend::setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta)
+{
+ BOOST_FOREACH(DNSBackend* db, backends) {
+ if(db->setDomainMetadata(name, kind, meta))
+ return true;
+ }
+ return false;
+}
+
+
void UeberBackend::reload()
{
for ( vector< DNSBackend * >::iterator i = backends.begin(); i != backends.end(); ++i )
void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
void getUpdatedMasters(vector<DomainInfo>* domains);
bool getDomainInfo(const string &domain, DomainInfo &di);
+
+ int addDomainKey(const string& name, const KeyData& key);
+ bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
+ bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
+ bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
+
void alsoNotifies(const string &domain, set<string> *ips);
void rediscover(string* status=0);
void reload();