]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dbdnsseckeeper.cc
Standardize license text in all PDNS files
[thirdparty/pdns.git] / pdns / dbdnsseckeeper.cc
CommitLineData
882358c8 1/*
12471842
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
c0273500
BH
25#include "dnsseckeeper.hh"
26#include "dnssecinfra.hh"
27#include "ueberbackend.hh"
28#include "statbag.hh"
29#include <iostream>
fa8fd4d2 30
c0273500
BH
31#include <sys/stat.h>
32#include <sys/types.h>
33#include <fstream>
34#include <boost/algorithm/string.hpp>
35#include <boost/format.hpp>
36#include <boost/assign/std/vector.hpp> // for 'operator+=()'
37#include <boost/assign/list_inserter.hpp>
78bcb858 38#include "base64.hh"
157f806e
PD
39#include "cachecleaner.hh"
40#include "arguments.hh"
d473cb9a
BH
41
42
c0273500 43using namespace boost::assign;
9cb28241 44#include "namespaces.hh"
de43ec0f 45
c0273500 46
40fe813d 47DNSSECKeeper::keycache_t DNSSECKeeper::s_keycache;
d6f3dcdc 48DNSSECKeeper::metacache_t DNSSECKeeper::s_metacache;
18a144ef
BH
49pthread_rwlock_t DNSSECKeeper::s_metacachelock = PTHREAD_RWLOCK_INITIALIZER;
50pthread_rwlock_t DNSSECKeeper::s_keycachelock = PTHREAD_RWLOCK_INITIALIZER;
16f7d28d 51AtomicCounter DNSSECKeeper::s_ops;
157f806e 52time_t DNSSECKeeper::s_last_prune;
d473cb9a 53
675fa24c 54bool DNSSECKeeper::isSecuredZone(const DNSName& zone)
c0273500 55{
d3e7090c 56 if(isPresigned(zone))
d6f3dcdc 57 return true;
157f806e 58
8a95b04c
KM
59 keyset_t keys = getKeys(zone); // does the cache
60
ef7cd021 61 for(keyset_t::value_type& val : keys) {
ade1b1e9
BH
62 if(val.second.active) {
63 return true;
64 }
c0273500 65 }
ade1b1e9 66 return false;
c0273500
BH
67}
68
675fa24c 69bool DNSSECKeeper::isPresigned(const DNSName& name)
d3e7090c 70{
9cb28241
BH
71 string meta;
72 getFromMeta(name, "PRESIGNED", meta);
73 return meta=="1";
d3e7090c 74}
c0273500 75
b6bd795c 76bool DNSSECKeeper::addKey(const DNSName& name, bool setSEPBit, int algorithm, int bits, bool active)
c0273500 77{
022e5e0b
BH
78 if(!bits) {
79 if(algorithm <= 10)
b6bd795c 80 throw runtime_error("Creating an algorithm " +std::to_string(algorithm)+" ("+algorithm2name(algorithm)+") key requires the size (in bits) to be passed");
022e5e0b 81 else {
45826dd7 82 if(algorithm == 12 || algorithm == 13 || algorithm == 250) // GOST, ECDSAP256SHA256, ED25519SHA512
022e5e0b 83 bits = 256;
45826dd7 84 else if(algorithm == 14) // ECDSAP384SHA384
022e5e0b
BH
85 bits = 384;
86 else {
335da0ba 87 throw runtime_error("Can't guess key size for algorithm "+std::to_string(algorithm));
022e5e0b
BH
88 }
89 }
90 }
699e6e37 91 DNSSECPrivateKey dspk;
b6bd795c 92 shared_ptr<DNSCryptoKeyEngine> dpk(DNSCryptoKeyEngine::make(algorithm));
699e6e37
BH
93 dpk->create(bits);
94 dspk.setKey(dpk);
95 dspk.d_algorithm = algorithm;
b6bd795c 96 dspk.d_flags = setSEPBit ? 257 : 256;
40fe813d 97 return addKey(name, dspk, active);
f7bcc763
BH
98}
99
627d2ca2
PD
100void DNSSECKeeper::clearAllCaches() {
101 {
18a144ef 102 WriteLock l(&s_keycachelock);
627d2ca2
PD
103 s_keycache.clear();
104 }
18a144ef 105 WriteLock l(&s_metacachelock);
627d2ca2
PD
106 s_metacache.clear();
107}
108
675fa24c 109void DNSSECKeeper::clearCaches(const DNSName& name)
5e91adff 110{
40fe813d 111 {
18a144ef 112 WriteLock l(&s_keycachelock);
40fe813d
BH
113 s_keycache.erase(name);
114 }
18a144ef 115 WriteLock l(&s_metacachelock);
0b7d7191 116 pair<metacache_t::iterator, metacache_t::iterator> range = s_metacache.equal_range(tie(name));
d6f3dcdc
BH
117 while(range.first != range.second)
118 s_metacache.erase(range.first++);
5e91adff
BH
119}
120
121
675fa24c 122bool DNSSECKeeper::addKey(const DNSName& name, const DNSSECPrivateKey& dpk, bool active)
f7bcc763 123{
5e91adff 124 clearCaches(name);
c0273500 125 DNSBackend::KeyData kd;
7ddd79a7 126 kd.flags = dpk.d_flags; // the dpk doesn't get stored, only they key part
c0273500 127 kd.active = active;
189bb9d2 128 kd.content = dpk.getKey()->convertToISC();
c0273500 129 // now store it
936eb34a 130 return d_keymetadb->addDomainKey(name, kd) >= 0; // >= 0 == s
c0273500
BH
131}
132
133
134static bool keyCompareByKindAndID(const DNSSECKeeper::keyset_t::value_type& a, const DNSSECKeeper::keyset_t::value_type& b)
135{
b6bd795c
PL
136 return make_pair(!a.second.keyType, a.second.id) <
137 make_pair(!b.second.keyType, b.second.id);
c0273500
BH
138}
139
675fa24c 140DNSSECPrivateKey DNSSECKeeper::getKeyById(const DNSName& zname, unsigned int id)
c0273500 141{
c0273500 142 vector<DNSBackend::KeyData> keys;
936eb34a 143 d_keymetadb->getDomainKeys(zname, 0, keys);
ef7cd021 144 for(const DNSBackend::KeyData& kd : keys) {
c0273500
BH
145 if(kd.id != id)
146 continue;
147
148 DNSSECPrivateKey dpk;
699e6e37 149 DNSKEYRecordContent dkrc;
8d9f38f2 150 dpk.setKey(shared_ptr<DNSCryptoKeyEngine>(DNSCryptoKeyEngine::makeFromISCString(dkrc, kd.content)));
c0273500 151 dpk.d_flags = kd.flags;
a254438f 152 dpk.d_algorithm = dkrc.d_algorithm;
c0273500 153
a254438f
BH
154 if(dpk.d_algorithm == 5 && getNSEC3PARAM(zname)) {
155 dpk.d_algorithm += 2;
156 }
c0273500
BH
157
158 return dpk;
159 }
335da0ba 160 throw runtime_error("Can't find a key with id "+std::to_string(id)+" for zone '"+zname.toString()+"'");
c0273500
BH
161}
162
163
675fa24c 164bool DNSSECKeeper::removeKey(const DNSName& zname, unsigned int id)
c0273500 165{
5e91adff 166 clearCaches(zname);
a84a8203 167 return d_keymetadb->removeDomainKey(zname, id);
c0273500
BH
168}
169
675fa24c 170bool DNSSECKeeper::deactivateKey(const DNSName& zname, unsigned int id)
c0273500 171{
5e91adff 172 clearCaches(zname);
a84a8203 173 return d_keymetadb->deactivateDomainKey(zname, id);
c0273500
BH
174}
175
675fa24c 176bool DNSSECKeeper::activateKey(const DNSName& zname, unsigned int id)
c0273500 177{
5e91adff 178 clearCaches(zname);
a84a8203 179 return d_keymetadb->activateDomainKey(zname, id);
c0273500
BH
180}
181
d6f3dcdc 182
675fa24c 183void DNSSECKeeper::getFromMeta(const DNSName& zname, const std::string& key, std::string& value)
c0273500 184{
030850a9 185 static int ttl = ::arg().asNum("domain-metadata-cache-ttl");
d6f3dcdc 186 value.clear();
5e91adff 187 unsigned int now = time(0);
157f806e 188
16f7d28d 189 if(!((++s_ops) % 100000)) {
157f806e
PD
190 cleanup();
191 }
192
030850a9 193 if (ttl > 0) {
18a144ef 194 ReadLock l(&s_metacachelock);
d473cb9a 195
d6f3dcdc
BH
196 metacache_t::const_iterator iter = s_metacache.find(tie(zname, key));
197 if(iter != s_metacache.end() && iter->d_ttd > now) {
198 value = iter->d_value;
199 return;
d473cb9a 200 }
22c5aa60 201 }
d473cb9a 202 vector<string> meta;
936eb34a 203 d_keymetadb->getDomainMetadata(zname, key, meta);
d6f3dcdc
BH
204 if(!meta.empty())
205 value=*meta.begin();
030850a9
RG
206
207 if (ttl > 0) {
208 METACacheEntry nce;
209 nce.d_domain=zname;
210 nce.d_ttd = now + ttl;
211 nce.d_key= key;
212 nce.d_value = value;
213 {
214 WriteLock l(&s_metacachelock);
215 replacing_insert(s_metacache, nce);
216 }
d473cb9a 217 }
d6f3dcdc
BH
218}
219
4192773a
KM
220void DNSSECKeeper::getSoaEdit(const DNSName& zname, std::string& value)
221{
222 static const string soaEdit(::arg()["default-soa-edit"]);
223 static const string soaEditSigned(::arg()["default-soa-edit-signed"]);
224
225 getFromMeta(zname, "SOA-EDIT", value);
226
227 if ((!soaEdit.empty() || !soaEditSigned.empty()) && value.empty() && !isPresigned(zname)) {
228 if (!soaEditSigned.empty() && isSecuredZone(zname))
229 value=soaEditSigned;
230 if (value.empty())
231 value=soaEdit;
232 }
233
234 return;
235}
236
e903706d 237uint64_t DNSSECKeeper::dbdnssecCacheSizes(const std::string& str)
238{
239 if(str=="meta-cache-size") {
240 ReadLock l(&s_metacachelock);
241 return s_metacache.size();
242 }
243 else if(str=="key-cache-size") {
244 ReadLock l(&s_keycachelock);
245 return s_keycache.size();
246 }
247 return (uint64_t)-1;
248}
249
675fa24c 250bool DNSSECKeeper::getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow)
d6f3dcdc
BH
251{
252 string value;
253 getFromMeta(zname, "NSEC3PARAM", value);
5935cede 254 if(value.empty()) { // "no NSEC3"
d6f3dcdc 255 return false;
5935cede 256 }
28b66a94
KM
257
258 static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations");
c0273500 259 if(ns3p) {
d6f3dcdc 260 NSEC3PARAMRecordContent* tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, value));
c0273500
BH
261 *ns3p = *tmp;
262 delete tmp;
28b66a94
KM
263 if (ns3p->d_iterations > maxNSEC3Iterations) {
264 ns3p->d_iterations = maxNSEC3Iterations;
f43c4448 265 L<<Logger::Error<<"Number of NSEC3 iterations for zone '"<<zname<<"' is above 'max-nsec3-iterations'. Value adjusted to: "<<maxNSEC3Iterations<<endl;
28b66a94 266 }
c7fbe6c9
PL
267 if (ns3p->d_algorithm != 1) {
268 L<<Logger::Error<<"Invalid hash algorithm for NSEC3: '"<<std::to_string(ns3p->d_algorithm)<<"', setting to 1 for zone '"<<zname<<"'."<<endl;
269 ns3p->d_algorithm = 1;
270 }
c0273500 271 }
d6f3dcdc
BH
272 if(narrow) {
273 getFromMeta(zname, "NSEC3NARROW", value);
274 *narrow = (value=="1");
275 }
c0273500
BH
276 return true;
277}
278
675fa24c 279bool DNSSECKeeper::setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& ns3p, const bool& narrow)
c0273500 280{
28b66a94
KM
281 static int maxNSEC3Iterations=::arg().asNum("max-nsec3-iterations");
282 if (ns3p.d_iterations > maxNSEC3Iterations)
675fa24c 283 throw runtime_error("Can't set NSEC3PARAM for zone '"+zname.toString()+"': number of NSEC3 iterations is above 'max-nsec3-iterations'");
28b66a94 284
c7fbe6c9
PL
285 if (ns3p.d_algorithm != 1)
286 throw runtime_error("Invalid hash algorithm for NSEC3: '"+std::to_string(ns3p.d_algorithm)+"' for zone '"+zname.toString()+"'. The only valid value is '1'");
287
5e91adff 288 clearCaches(zname);
c0273500
BH
289 string descr = ns3p.getZoneRepresentation();
290 vector<string> meta;
291 meta.push_back(descr);
a84a8203
PD
292 if (d_keymetadb->setDomainMetadata(zname, "NSEC3PARAM", meta)) {
293 meta.clear();
294
295 if(narrow)
296 meta.push_back("1");
297
298 return d_keymetadb->setDomainMetadata(zname, "NSEC3NARROW", meta);
299 }
300 return false;
c0273500
BH
301}
302
675fa24c 303bool DNSSECKeeper::unsetNSEC3PARAM(const DNSName& zname)
c0273500 304{
5e91adff 305 clearCaches(zname);
a84a8203 306 return (d_keymetadb->setDomainMetadata(zname, "NSEC3PARAM", vector<string>()) && d_keymetadb->setDomainMetadata(zname, "NSEC3NARROW", vector<string>()));
c0273500
BH
307}
308
309
675fa24c 310bool DNSSECKeeper::setPresigned(const DNSName& zname)
d3e7090c
BH
311{
312 clearCaches(zname);
313 vector<string> meta;
314 meta.push_back("1");
a84a8203 315 return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", meta);
d3e7090c
BH
316}
317
675fa24c 318bool DNSSECKeeper::unsetPresigned(const DNSName& zname)
d3e7090c
BH
319{
320 clearCaches(zname);
a84a8203 321 return d_keymetadb->setDomainMetadata(zname, "PRESIGNED", vector<string>());
d3e7090c
BH
322}
323
ef542223
PL
324/**
325 * Add domainmetadata to allow publishing CDS records for zone zname
326 *
327 * @param zname DNSName of the zone
328 * @param digestAlgos string with comma-separated numbers that describe the
329 * used digest algorithms. This is copied to the database
330 * verbatim
331 * @return true if the data was inserted, false otherwise
332 */
333bool DNSSECKeeper::setPublishCDS(const DNSName& zname, const string& digestAlgos)
334{
335 clearCaches(zname);
336 vector<string> meta;
337 meta.push_back(digestAlgos);
0900d2d3 338 return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDS", meta);
ef542223
PL
339}
340
341/**
342 * Remove domainmetadata to stop publishing CDS records for zone zname
343 *
344 * @param zname DNSName of the zone
345 * @return true if the operation was successful, false otherwise
346 */
347bool DNSSECKeeper::unsetPublishCDS(const DNSName& zname)
348{
349 clearCaches(zname);
0900d2d3 350 return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDS", vector<string>());
ef542223
PL
351}
352
088370cd
PL
353/**
354 * Add domainmetadata to allow publishing CDNSKEY records.for zone zname
355 *
356 * @param zname DNSName of the zone
357 * @return true if the data was inserted, false otherwise
358 */
359bool DNSSECKeeper::setPublishCDNSKEY(const DNSName& zname)
360{
361 clearCaches(zname);
362 vector<string> meta;
363 meta.push_back("1");
0900d2d3 364 return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDNSKEY", meta);
088370cd
PL
365}
366
367/**
368 * Remove domainmetadata to stop publishing CDNSKEY records for zone zname
369 *
370 * @param zname DNSName of the zone
371 * @return true if the operation was successful, false otherwise
372 */
373bool DNSSECKeeper::unsetPublishCDNSKEY(const DNSName& zname)
374{
375 clearCaches(zname);
0900d2d3 376 return d_keymetadb->setDomainMetadata(zname, "PUBLISH-CDNSKEY", vector<string>());
088370cd 377}
d3e7090c 378
f889ab99
PL
379/**
380 * Returns all keys that are used to sign the DNSKEY RRSet in a zone
381 *
9091cf89 382 * @param zname DNSName of the zone
f889ab99
PL
383 * @return a keyset_t with all keys that are used to sign the DNSKEY
384 * RRSet (these are the entrypoint(s) to the zone)
385 */
9091cf89 386DNSSECKeeper::keyset_t DNSSECKeeper::getEntryPoints(const DNSName& zname)
f889ab99
PL
387{
388 DNSSECKeeper::keyset_t ret;
9091cf89 389 DNSSECKeeper::keyset_t keys = getKeys(zname);
f889ab99 390
b6bd795c
PL
391 for(auto const &keymeta : keys)
392 if(keymeta.second.active && (keymeta.second.keyType == KSK || keymeta.second.keyType == CSK))
f889ab99 393 ret.push_back(keymeta);
f889ab99
PL
394 return ret;
395}
396
b6bd795c 397DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, bool useCache)
c0273500 398{
030850a9 399 static int ttl = ::arg().asNum("dnssec-key-cache-ttl");
5e91adff 400 unsigned int now = time(0);
157f806e 401
16f7d28d 402 if(!((++s_ops) % 100000)) {
157f806e
PD
403 cleanup();
404 }
405
030850a9 406 if (useCache && ttl > 0) {
18a144ef 407 ReadLock l(&s_keycachelock);
40fe813d 408 keycache_t::const_iterator iter = s_keycache.find(zone);
b6bd795c
PL
409
410 if(iter != s_keycache.end() && iter->d_ttd > now) {
40fe813d 411 keyset_t ret;
b6bd795c
PL
412 for(const keyset_t::value_type& value : iter->d_keys)
413 ret.push_back(value);
40fe813d 414 return ret;
7aff7ead 415 }
b6bd795c
PL
416 }
417
418 keyset_t retkeyset;
3971cf53 419 vector<DNSBackend::KeyData> dbkeyset;
b6bd795c 420
936eb34a 421 d_keymetadb->getDomainKeys(zone, 0, dbkeyset);
b6bd795c
PL
422
423 // Determine the algorithms that have a KSK/ZSK split
424 set<uint8_t> algoSEP, algoNoSEP;
425 vector<uint8_t> algoHasSeparateKSK;
426 for(const DNSBackend::KeyData &keydata : dbkeyset) {
c0273500 427 DNSSECPrivateKey dpk;
b6bd795c
PL
428 DNSKEYRecordContent dkrc;
429
430 dpk.setKey(shared_ptr<DNSCryptoKeyEngine>(DNSCryptoKeyEngine::makeFromISCString(dkrc, keydata.content)));
c0273500 431
b6bd795c
PL
432 if(keydata.active) {
433 if(keydata.flags == 257)
434 algoSEP.insert(dkrc.d_algorithm);
435 else
436 algoNoSEP.insert(dkrc.d_algorithm);
437 }
438 }
439 set_intersection(algoSEP.begin(), algoSEP.end(), algoNoSEP.begin(), algoNoSEP.end(), std::back_inserter(algoHasSeparateKSK));
440
441 for(DNSBackend::KeyData& kd : dbkeyset)
442 {
443 DNSSECPrivateKey dpk;
699e6e37 444 DNSKEYRecordContent dkrc;
b6bd795c 445
8d9f38f2 446 dpk.setKey(shared_ptr<DNSCryptoKeyEngine>(DNSCryptoKeyEngine::makeFromISCString(dkrc, kd.content)));
b6bd795c 447
c0273500 448 dpk.d_flags = kd.flags;
a254438f 449 dpk.d_algorithm = dkrc.d_algorithm;
89c8b2ce 450 if(dpk.d_algorithm == 5 && getNSEC3PARAM(zone))
a254438f 451 dpk.d_algorithm+=2;
b6bd795c 452
c0273500
BH
453 KeyMetaData kmd;
454
455 kmd.active = kd.active;
b6bd795c 456 kmd.hasSEPBit = (kd.flags == 257);
c0273500 457 kmd.id = kd.id;
b6bd795c
PL
458
459 if (find(algoHasSeparateKSK.begin(), algoHasSeparateKSK.end(), dpk.d_algorithm) == algoHasSeparateKSK.end())
460 kmd.keyType = CSK;
461 else if(kmd.hasSEPBit)
462 kmd.keyType = KSK;
463 else
464 kmd.keyType = ZSK;
465
466 retkeyset.push_back(make_pair(dpk, kmd));
c0273500 467 }
7aff7ead 468 sort(retkeyset.begin(), retkeyset.end(), keyCompareByKindAndID);
b6bd795c 469
030850a9
RG
470 if (ttl > 0) {
471 KeyCacheEntry kce;
472 kce.d_domain=zone;
473 kce.d_keys = retkeyset;
474 kce.d_ttd = now + ttl;
475 {
476 WriteLock l(&s_keycachelock);
477 replacing_insert(s_keycache, kce);
478 }
40fe813d 479 }
030850a9 480
7aff7ead 481 return retkeyset;
c0273500
BH
482}
483
8ca3ea33
RG
484bool DNSSECKeeper::checkKeys(const DNSName& zone)
485{
486 vector<DNSBackend::KeyData> dbkeyset;
487 d_keymetadb->getDomainKeys(zone, 0, dbkeyset);
488
489 for(const DNSBackend::KeyData &keydata : dbkeyset) {
490 DNSKEYRecordContent dkrc;
491 shared_ptr<DNSCryptoKeyEngine> dke(DNSCryptoKeyEngine::makeFromISCString(dkrc, keydata.content));
45c2bc60 492 if (!dke->checkKey()) {
8ca3ea33
RG
493 return false;
494 }
495 }
496
497 return true;
498}
499
675fa24c
PD
500bool DNSSECKeeper::getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname,
501 const DNSName& wildcardname, const QType& qtype,
e693ff5a 502 DNSResourceRecord::Place signPlace, vector<DNSResourceRecord>& rrsigs, uint32_t signTTL)
d3e7090c 503{
f1485b68 504 // cerr<<"Doing DB lookup for precomputed RRSIGs for '"<<(wildcardname.empty() ? qname : wildcardname)<<"'"<<endl;
232f0877 505 SOAData sd;
79ba7763 506 if(!db.getSOAUncached(signer, sd)) {
232f0877
CH
507 DLOG(L<<"Could not get SOA for domain"<<endl);
508 return false;
509 }
675fa24c 510 db.lookup(QType(QType::RRSIG), wildcardname.countLabels() ? wildcardname : qname, NULL, sd.domain_id);
232f0877
CH
511 DNSResourceRecord rr;
512 while(db.get(rr)) {
513 // cerr<<"Considering for '"<<qtype.getName()<<"' RRSIG '"<<rr.content<<"'\n";
514 vector<string> parts;
515 stringtok(parts, rr.content);
675fa24c 516 if(parts[0] == qtype.getName() && DNSName(parts[7])==signer) {
232f0877 517 // cerr<<"Got it"<<endl;
675fa24c 518 if (wildcardname.countLabels())
232f0877 519 rr.qname = qname;
e693ff5a 520 rr.d_place = signPlace;
232f0877
CH
521 rr.ttl = signTTL;
522 rrsigs.push_back(rr);
523 }
e125fc69 524 // else cerr<<"Skipping!"<<endl;
232f0877
CH
525 }
526 return true;
d3e7090c 527}
78bcb858 528
675fa24c 529bool DNSSECKeeper::TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname)
78bcb858
BH
530{
531 vector<string> allowed;
532
936eb34a 533 d_keymetadb->getDomainMetadata(zone, "TSIG-ALLOW-AXFR", allowed);
78bcb858 534
ef7cd021 535 for(const string& dbkey : allowed) {
675fa24c 536 if(DNSName(dbkey)==keyname)
78bcb858
BH
537 return true;
538 }
539 return false;
540}
29b92d6f 541
675fa24c 542bool DNSSECKeeper::getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname)
29b92d6f
BH
543{
544 vector<string> keynames;
936eb34a 545 d_keymetadb->getDomainMetadata(zone, "AXFR-MASTER-TSIG", keynames);
675fa24c 546 keyname->trimToLabels(0);
29b92d6f
BH
547
548 // XXX FIXME this should check for a specific master!
ef7cd021 549 for(const string& dbkey : keynames) {
675fa24c 550 *keyname=DNSName(dbkey);
29b92d6f
BH
551 return true;
552 }
553 return false;
554}
157f806e
PD
555
556void DNSSECKeeper::cleanup()
557{
558 struct timeval now;
559 Utility::gettimeofday(&now, 0);
560
561 if(now.tv_sec - s_last_prune > (time_t)(30)) {
562 {
18a144ef 563 WriteLock l(&s_metacachelock);
157f806e
PD
564 pruneCollection(s_metacache, ::arg().asNum("max-cache-entries"));
565 }
566 {
18a144ef 567 WriteLock l(&s_keycachelock);
157f806e
PD
568 pruneCollection(s_keycache, ::arg().asNum("max-cache-entries"));
569 }
570 s_last_prune=time(0);
571 }
627d2ca2 572}