From: Aki Tuomi Date: Sat, 15 Jun 2013 13:54:59 +0000 (+0300) Subject: Basic TSIG key management infrastructure X-Git-Tag: rec-3.6.0-rc1~468^2~22 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6f872b7852ba42897a5976ed9cdf91dddcfd0d5f;p=thirdparty%2Fpdns.git Basic TSIG key management infrastructure --- diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index 2215bec537..bb50c7c856 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -65,6 +65,12 @@ struct DomainInfo } }; +struct TSIGKey { + std::string name; + std::string algorithm; + std::string key; +}; + class DNSPacket; @@ -132,6 +138,9 @@ public: virtual bool deactivateDomainKey(const string& name, unsigned int id) { return false; } virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; } + virtual bool setTSIGKey(const string& name, const string& algorithm, const string& content) { return false; } + virtual bool deleteTSIGKey(const string& name) { return false; } + virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys) { return false; } virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after) { diff --git a/pdns/dnsseckeeper.hh b/pdns/dnsseckeeper.hh index 514b227d27..853e26645f 100644 --- a/pdns/dnsseckeeper.hh +++ b/pdns/dnsseckeeper.hh @@ -86,7 +86,7 @@ public: bool isPresigned(const std::string& zname); bool setPresigned(const std::string& zname); bool unsetPresigned(const std::string& zname); - + bool TSIGGrantsAccess(const string& zone, const string& keyname, const string& algorithm); bool getTSIGForAccess(const string& zone, const string& master, string* keyname); diff --git a/pdns/pdnssec.cc b/pdns/pdnssec.cc index ebf381f359..173eaba512 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -960,7 +960,8 @@ try cerr<<"show-zone ZONE Show DNSSEC (public) key details about a zone\n"; cerr<<"unset-nsec3 ZONE Switch back to NSEC\n"; cerr<<"unset-presigned ZONE No longer use presigned RRSIGs\n"; - cerr<<"test-schema ZONE Test DB schema - will create ZONE\n\n"; + cerr<<"test-schema ZONE Test DB schema - will create ZONE\n"; + cerr<<"import-tsig-key ZONE ALGORITHM KEY Import TSIG key for zone\n\n"; cerr<convertToISC() << endl; + } else if (cmds[0]=="generate-tsig-key") { + if (cmds.size() < 3) { + cerr << "Syntax: " << cmds[0] << " name (hmac-md5|hmac-sha1|hmac-sha224|hmac-sha256|hmac-sha384|hmac-sha512)" << endl; + return 0; + } + string name = cmds[1]; + string algo = cmds[2]; + string key; + char tmpkey[64]; + + size_t klen; + if (algo == "hmac-md5") { + klen = 32; + } else if (algo == "hmac-sha1") { + klen = 32; + } else if (algo == "hmac-sha224") { + klen = 32; + } else if (algo == "hmac-sha256") { + klen = 64; + } else if (algo == "hmac-sha384") { + klen = 64; + } else if (algo == "hmac-sha512") { + klen = 64; + } + + ifstream keyin("/dev/random", ifstream::in|ifstream::binary); + // read and hash data + keyin.read(tmpkey, klen); + key = Base64Encode(std::string(tmpkey, klen)); + + UeberBackend B("default"); + if (B.setTSIGKey(name, algo, key)) { + cout << "Create new TSIG key " << name << " " << algo << " " << key << endl; + } else { + cout << "Failure storing new TSIG key " << name << " " << algo << " " << key << endl; + return 1; + } + return 0; + } else if (cmds[0]=="import-tsig-key") { + if (cmds.size() < 4) { + cerr << "Syntax: " << cmds[0] << " name algorithm key" << endl; + return 0; + } + string name = cmds[1]; + string algo = cmds[2]; + string key = cmds[3]; + + UeberBackend B("default"); + if (B.setTSIGKey(name, algo, key)) { + cout << "Imported TSIG key " << name << " " << algo << endl; + } else { + cout << "Failure importing TSIG key " << name << " " << algo << endl; + return 1; + } + return 0; + } else if (cmds[0]=="delete-tsig-key") { + if (cmds.size() < 2) { + cerr << "Syntax: " << cmds[0] << " name" << endl; + return 0; + } + string name = cmds[1]; + string algo = cmds[2]; + + UeberBackend B("default"); + if (B.deleteTSIGKey(name)) { + cout << "Deleted TSIG key " << name << endl; + } else { + cout << "Failure deleting TSIG key " << name << endl; + return 1; + } + return 0; + } else if (cmds[0]=="list-tsig-keys") { + std::vector keys; + UeberBackend B("default"); + if (B.getTSIGKeys(keys)) { + BOOST_FOREACH(const struct TSIGKey &key, keys) { + cout << key.name << " " << key.algorithm << " " << key.key << endl; + } + } + return 0; + } else if (cmds[0]=="enable-tsig-key") { + if (cmds.size() < 3) { + cerr << "Syntax: " << cmds[0] << " zone name" << endl; + return 0; + } + string zname = cmds[1]; + string name = cmds[2]; + + UeberBackend B("default"); + std::vector meta; + if (!B.getDomainMetadata(zname, "TSIG-ALLOW-AXFR", meta)) { + cout << "Failure enabling TSIG key " << name << " for " << zname << endl; + return 1; + } + bool found = false; + BOOST_FOREACH(std::string tmpname, meta) { + if (tmpname == name) { found = true; break; } + } + if (!found) meta.push_back(name); + if (B.setDomainMetadata(zname, "TSIG-ALLOW-AXFR", meta)) { + cout << "Enabled TSIG key " << name << " for " << zname << endl; + } else { + cout << "Failure enabling TSIG key " << name << " for " << zname << endl; + return 1; + } + return 0; + } else if (cmds[0]=="disable-tsig-key") { + if (cmds.size() < 3) { + cerr << "Syntax: " << cmds[0] << " zone name" << endl; + return 0; + } + string zname = cmds[1]; + string name = cmds[2]; + + UeberBackend B("default"); + std::vector meta; + if (!B.getDomainMetadata(zname, "TSIG-ALLOW-AXFR", meta)) { + cout << "Failure disabling TSIG key " << name << " for " << zname << endl; + return 1; + } + std::vector::iterator iter = meta.begin(); + for(;iter != meta.end(); iter++) if (*iter == name) break; + if (iter != meta.end()) meta.erase(iter); + if (B.setDomainMetadata(zname, "TSIG-ALLOW-AXFR", meta)) { + cout << "Disabled TSIG key " << name << " for " << zname << endl; + } else { + cout << "Failure disabling TSIG key " << name << " for " << zname << endl; + return 1; + } + return 0; } else { - cerr<<"Unknown command '"<setTSIGKey(name, algorithm, content)) + return true; + } + return false; +} + +bool UeberBackend::deleteTSIGKey(const string& name) +{ + BOOST_FOREACH(DNSBackend* db, backends) { + if(db->deleteTSIGKey(name)) + return true; + } + return false; +} + +bool UeberBackend::getTSIGKeys(std::vector< struct TSIGKey > &keys) +{ + BOOST_FOREACH(DNSBackend* db, backends) { + db->getTSIGKeys(keys); + } + return true; +} + + 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 ff2d582556..d0ef671cbc 100644 --- a/pdns/ueberbackend.hh +++ b/pdns/ueberbackend.hh @@ -134,7 +134,10 @@ public: bool deactivateDomainKey(const string& name, unsigned int id); bool getTSIGKey(const string& name, string* algorithm, string* content); - + bool setTSIGKey(const string& name, const string& algorithm, const string& content); + bool deleteTSIGKey(const string& name); + bool getTSIGKeys(std::vector< struct TSIGKey > &keys); + void alsoNotifies(const string &domain, set *ips); void rediscover(string* status=0); void reload();