From: Bert Hubert Date: Sat, 1 Jan 2011 21:19:02 +0000 (+0000) Subject: hook up the dbdnsseckeeper to everything, implement (most) methods in the generic... X-Git-Tag: auth-3.0~466 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c0273500c1bfbd1004b82b14342136f65a9ffb6a;p=pdns hook up the dbdnsseckeeper to everything, implement (most) methods in the generic backend git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1781 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index f49887c5c..b93ca008c 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -18,6 +18,7 @@ using namespace std; #include "pdns/arguments.hh" #include #include +#include using namespace boost; void GSQLBackend::setNotified(uint32_t domain_id, uint32_t serial) @@ -241,6 +242,12 @@ GSQLBackend::GSQLBackend(const string &mode, const string &suffix) 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) @@ -303,6 +310,86 @@ retryBefore: 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& 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<<"'"<& 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& 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) { diff --git a/pdns/backends/gsql/gsqlbackend.hh b/pdns/backends/gsql/gsqlbackend.hh index 51b9cec91..ee9e9aa89 100644 --- a/pdns/backends/gsql/gsqlbackend.hh +++ b/pdns/backends/gsql/gsqlbackend.hh @@ -43,7 +43,10 @@ public: 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& keys); + bool getDomainMetadata(const string& name, const std::string& kind, std::vector& meta); + bool setDomainMetadata(const string& name, const std::string& kind, const std::vector& meta); private: string d_qname; QType d_qtype; @@ -78,6 +81,10 @@ private: string d_afterOrderQuery; string d_setOrderAuthQuery; + string d_AddDomainKeyQuery; + string d_ListDomainKeysQuery; + string d_GetDomainMetadataQuery; + string d_SetDomainMetadataQuery; protected: bool d_dnssecQueries; }; diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc new file mode 100644 index 000000000..6a8571c87 --- /dev/null +++ b/pdns/dbdnsseckeeper.cc @@ -0,0 +1,177 @@ +#include "dnsseckeeper.hh" +#include "dnssecinfra.hh" +#include "ueberbackend.hh" +#include "statbag.hh" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // for 'operator+=()' +#include +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 "<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 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(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 meta; + db.getDomainMetadata(zname, "NSEC3PARAM", meta); + + if(meta.empty()) + return false; + + if(ns3p) { + string descr = *meta.begin(); + reportAllTypes(); + NSEC3PARAMRecordContent* tmp=dynamic_cast(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, descr)); + if(!tmp) { + cerr<<"descr: '"< 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 dbkeyset; + + db.getDomainKeys(zone, 0, dbkeyset); + // do db thing + //cerr<<"Here: received " < #include #include +#include #include "dns.hh" #include "arguments.hh" @@ -98,6 +99,42 @@ bool UeberBackend::getDomainInfo(const string &domain, DomainInfo &di) 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& 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& 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& 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 ) diff --git a/pdns/ueberbackend.hh b/pdns/ueberbackend.hh index e2fc6788f..27f07bc57 100644 --- a/pdns/ueberbackend.hh +++ b/pdns/ueberbackend.hh @@ -122,6 +122,12 @@ public: void getUnfreshSlaveInfos(vector* domains); void getUpdatedMasters(vector* 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& keys); + bool getDomainMetadata(const string& name, const std::string& kind, std::vector& meta); + bool setDomainMetadata(const string& name, const std::string& kind, const std::vector& meta); + void alsoNotifies(const string &domain, set *ips); void rediscover(string* status=0); void reload();