]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/dnsseckeeper.hh
Merge pull request #9099 from PowerDNS/omoerbeek-patch-1
[thirdparty/pdns.git] / pdns / dnsseckeeper.hh
CommitLineData
0ea9281e 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 */
22#pragma once
4691b2df 23#include <string>
4691b2df
BH
24#include <string.h>
25#include <vector>
bed962b5 26#include <boost/logic/tribool.hpp>
d473cb9a 27#include <boost/multi_index_container.hpp>
9b2897e1 28#include <boost/multi_index/hashed_index.hpp>
d473cb9a
BH
29#include <boost/multi_index/ordered_index.hpp>
30#include <boost/tuple/tuple_comparison.hpp>
31#include <boost/multi_index/key_extractors.hpp>
32#include <boost/multi_index/sequenced_index.hpp>
edca4841 33#include "dnssecinfra.hh"
4691b2df 34#include "dnsrecords.hh"
e0d84497 35#include "ueberbackend.hh"
0ddde5fb 36#include "lock.hh"
4691b2df 37
edca4841 38using namespace ::boost::multi_index;
4691b2df 39
936eb34a 40class DNSSECKeeper : public boost::noncopyable
4691b2df 41{
20002664 42public:
b6bd795c
PL
43 enum keytype_t { KSK, ZSK, CSK };
44 enum keyalgorithm_t : uint8_t {
45 RSAMD5=1,
46 DH=2,
47 DSA=3,
48 RSASHA1=5,
49 DSANSEC3SHA1=6,
50 RSASHA1NSEC3SHA1=7,
51 RSASHA256=8,
52 RSASHA512=10,
53 ECCGOST=12,
54 ECDSA256=13,
55 ECDSA384=14,
21a8834a
KM
56 ED25519=15,
57 ED448=16
b6bd795c
PL
58 };
59
8455425c 60 enum dsdigestalgorithm_t : uint8_t {
690b86b7
OM
61 DIGEST_SHA1=1,
62 DIGEST_SHA256=2,
63 DIGEST_GOST=3,
64 DIGEST_SHA384=4
8455425c
RG
65 };
66
20002664
BH
67 struct KeyMetaData
68 {
3b8256e2 69 string fname;
bed962b5 70 unsigned int id;
20002664 71 bool active;
b6bd795c
PL
72 keytype_t keyType;
73 bool hasSEPBit;
33918299 74 bool published;
d473cb9a 75 };
b6bd795c 76 typedef std::pair<DNSSECPrivateKey, KeyMetaData> keymeta_t;
d473cb9a 77 typedef std::vector<keymeta_t > keyset_t;
dfee9ed6 78
b6bd795c
PL
79 static string keyTypeToString(const keytype_t &keyType)
80 {
81 switch(keyType) {
82 case DNSSECKeeper::KSK:
83 return("KSK");
84 case DNSSECKeeper::ZSK:
85 return("ZSK");
86 case DNSSECKeeper::CSK:
87 return("CSK");
88 default:
89 return("UNKNOWN");
90 }
91 }
92
c29d2add
PL
93 /*
94 * Returns the algorithm number based on the mnemonic (or old PowerDNS value of) a string.
95 * See https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml for the mapping
96 */
b6bd795c
PL
97 static int shorthand2algorithm(const string &algorithm)
98 {
9d858a77
PL
99 if (pdns_iequals(algorithm, "rsamd5")) return RSAMD5;
100 if (pdns_iequals(algorithm, "dh")) return DH;
101 if (pdns_iequals(algorithm, "dsa")) return DSA;
102 if (pdns_iequals(algorithm, "rsasha1")) return RSASHA1;
103 if (pdns_iequals(algorithm, "dsa-nsec3-sha1")) return DSANSEC3SHA1;
104 if (pdns_iequals(algorithm, "rsasha1-nsec3-sha1")) return RSASHA1NSEC3SHA1;
105 if (pdns_iequals(algorithm, "rsasha256")) return RSASHA256;
106 if (pdns_iequals(algorithm, "rsasha512")) return RSASHA512;
107 if (pdns_iequals(algorithm, "ecc-gost")) return ECCGOST;
108 if (pdns_iequals(algorithm, "gost")) return ECCGOST;
109 if (pdns_iequals(algorithm, "ecdsa256")) return ECDSA256;
110 if (pdns_iequals(algorithm, "ecdsap256sha256")) return ECDSA256;
111 if (pdns_iequals(algorithm, "ecdsa384")) return ECDSA384;
112 if (pdns_iequals(algorithm, "ecdsap384sha384")) return ECDSA384;
113 if (pdns_iequals(algorithm, "ed25519")) return ED25519;
114 if (pdns_iequals(algorithm, "ed448")) return ED448;
115 if (pdns_iequals(algorithm, "indirect")) return 252;
116 if (pdns_iequals(algorithm, "privatedns")) return 253;
117 if (pdns_iequals(algorithm, "privateoid")) return 254;
b6bd795c
PL
118 return -1;
119 }
120
c29d2add
PL
121 /*
122 * Returns the mnemonic from https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
123 */
b6bd795c
PL
124 static string algorithm2name(uint8_t algo) {
125 switch(algo) {
126 case 0:
127 case 4:
128 case 9:
129 case 11:
130 return "Reserved";
131 case RSAMD5:
132 return "RSAMD5";
133 case DH:
134 return "DH";
135 case DSA:
136 return "DSA";
137 case RSASHA1:
138 return "RSASHA1";
139 case DSANSEC3SHA1:
140 return "DSA-NSEC3-SHA1";
141 case RSASHA1NSEC3SHA1:
142 return "RSASHA1-NSEC3-SHA1";
143 case RSASHA256:
144 return "RSASHA256";
145 case RSASHA512:
146 return "RSASHA512";
147 case ECCGOST:
148 return "ECC-GOST";
149 case ECDSA256:
150 return "ECDSAP256SHA256";
151 case ECDSA384:
152 return "ECDSAP384SHA384";
9d3727e0
KM
153 case ED25519:
154 return "ED25519";
21a8834a
KM
155 case ED448:
156 return "ED448";
b6bd795c
PL
157 case 252:
158 return "INDIRECT";
159 case 253:
160 return "PRIVATEDNS";
161 case 254:
162 return "PRIVATEOID";
163 default:
164 return "Unallocated/Reserved";
165 }
166 }
167
e0d84497 168private:
936eb34a
BH
169 UeberBackend* d_keymetadb;
170 bool d_ourDB;
dfee9ed6 171
4691b2df 172public:
936eb34a 173 DNSSECKeeper() : d_keymetadb( new UeberBackend("key-only")), d_ourDB(true)
631580dd 174 {
936eb34a
BH
175
176 }
177
178 DNSSECKeeper(UeberBackend* db) : d_keymetadb(db), d_ourDB(false)
179 {
180 }
181
182 ~DNSSECKeeper()
183 {
184 if(d_ourDB)
185 delete d_keymetadb;
631580dd 186 }
40b3959a
RG
187
188 static uint64_t dbdnssecCacheSizes(const std::string& str);
189 static void clearAllCaches();
190 static void clearCaches(const DNSName& name);
191
7fa35c07 192 bool doesDNSSEC();
675fa24c 193 bool isSecuredZone(const DNSName& zone);
9091cf89 194 keyset_t getEntryPoints(const DNSName& zname);
b6bd795c 195 keyset_t getKeys(const DNSName& zone, bool useCache = true);
675fa24c 196 DNSSECPrivateKey getKeyById(const DNSName& zone, unsigned int id);
33918299
RG
197 bool addKey(const DNSName& zname, bool setSEPBit, int algorithm, int64_t& id, int bits=0, bool active=true, bool published=true);
198 bool addKey(const DNSName& zname, const DNSSECPrivateKey& dpk, int64_t& id, bool active=true, bool published=true);
675fa24c
PD
199 bool removeKey(const DNSName& zname, unsigned int id);
200 bool activateKey(const DNSName& zname, unsigned int id);
201 bool deactivateKey(const DNSName& zname, unsigned int id);
33918299
RG
202 bool publishKey(const DNSName& zname, unsigned int id);
203 bool unpublishKey(const DNSName& zname, unsigned int id);
ac3f3893 204 bool checkKeys(const DNSName& zname, vector<string>* errorMessages = nullptr);
675fa24c 205
675fa24c 206 bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
68fd1167 207 bool checkNSEC3PARAM(const NSEC3PARAMRecordContent& ns3p, string& msg);
675fa24c
PD
208 bool setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
209 bool unsetNSEC3PARAM(const DNSName& zname);
90ba52e0 210 bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector<DNSZoneRecord>& rrsigs, uint32_t signTTL);
675fa24c
PD
211 bool isPresigned(const DNSName& zname);
212 bool setPresigned(const DNSName& zname);
213 bool unsetPresigned(const DNSName& zname);
088370cd 214 bool setPublishCDNSKEY(const DNSName& zname);
c7094551 215 void getPublishCDNSKEY(const DNSName& zname, std::string& value);
088370cd 216 bool unsetPublishCDNSKEY(const DNSName& zname);
ef542223 217 bool setPublishCDS(const DNSName& zname, const string& digestAlgos);
c7094551 218 void getPublishCDS(const DNSName& zname, std::string& value);
ef542223 219 bool unsetPublishCDS(const DNSName& zname);
675fa24c
PD
220
221 bool TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname);
d622042f 222 bool getTSIGForAccess(const DNSName& zone, const ComboAddress& master, DNSName* keyname);
dfee9ed6 223
7da05748 224 void startTransaction(const DNSName& zone, int zone_id)
dfee9ed6 225 {
7da05748 226 (*d_keymetadb->backends.begin())->startTransaction(zone, zone_id);
dfee9ed6
BH
227 }
228
229 void commitTransaction()
230 {
627d2ca2 231 (*d_keymetadb->backends.begin())->commitTransaction();
dfee9ed6
BH
232 }
233
2fb19458
PD
234 void getFromMetaOrDefault(const DNSName& zname, const std::string& key, std::string& value, const std::string& defaultvalue);
235 bool getFromMeta(const DNSName& zname, const std::string& key, std::string& value);
4192773a 236 void getSoaEdit(const DNSName& zname, std::string& value);
cbe8b186 237 bool unSecureZone(const DNSName& zone, std::string& error, std::string& info);
59102608 238 bool rectifyZone(const DNSName& zone, std::string& error, std::string& info, bool doTransaction);
307994e7
RG
239
240 static void setMaxEntries(size_t maxEntries);
241
0ea9281e
BH
242private:
243
e903706d 244
d473cb9a
BH
245 struct KeyCacheEntry
246 {
247 typedef vector<DNSSECKeeper::keymeta_t> keys_t;
248
249 uint32_t getTTD() const
250 {
251 return d_ttd;
252 }
253
675fa24c 254 DNSName d_domain;
d473cb9a 255 mutable keys_t d_keys;
1336cf9a 256 unsigned int d_ttd;
d473cb9a
BH
257 };
258
d6f3dcdc 259 struct METACacheEntry
d473cb9a 260 {
d473cb9a
BH
261 uint32_t getTTD() const
262 {
263 return d_ttd;
264 }
265
675fa24c 266 DNSName d_domain;
2ae1be00 267 mutable std::string d_key, d_value;
2fb19458 268 mutable bool d_isset;
d473cb9a
BH
269 unsigned int d_ttd;
270
d473cb9a
BH
271 };
272
94306029
OM
273 struct KeyCacheTag{};
274 struct CompositeTag{};
275 struct SequencedTag{};
d473cb9a
BH
276
277 typedef multi_index_container<
278 KeyCacheEntry,
279 indexed_by<
9b2897e1
RG
280 hashed_unique<tag<KeyCacheTag>,member<KeyCacheEntry, DNSName, &KeyCacheEntry::d_domain> >,
281 sequenced<tag<SequencedTag>>
d473cb9a
BH
282 >
283 > keycache_t;
307994e7 284
d473cb9a 285 typedef multi_index_container<
d6f3dcdc 286 METACacheEntry,
d473cb9a 287 indexed_by<
94306029 288 ordered_unique<tag<CompositeTag>,
d6f3dcdc
BH
289 composite_key<
290 METACacheEntry,
675fa24c 291 member<METACacheEntry, DNSName, &METACacheEntry::d_domain> ,
d6f3dcdc 292 member<METACacheEntry, std::string, &METACacheEntry::d_key>
675fa24c 293 >, composite_key_compare<std::less<DNSName>, CIStringCompare> >,
94306029 294 sequenced<tag<SequencedTag>>
d473cb9a 295 >
d6f3dcdc 296 > metacache_t;
d473cb9a 297
157f806e
PD
298 void cleanup();
299
40fe813d 300 static keycache_t s_keycache;
d6f3dcdc 301 static metacache_t s_metacache;
0ddde5fb
RG
302 static ReadWriteLock s_metacachelock;
303 static ReadWriteLock s_keycachelock;
16f7d28d 304 static AtomicCounter s_ops;
157f806e 305 static time_t s_last_prune;
307994e7 306 static size_t s_maxEntries;
e74f866a
RG
307
308public:
309 void preRemoval(const KeyCacheEntry&)
310 {
311 }
312 void preRemoval(const METACacheEntry&)
313 {
314 }
4691b2df
BH
315};
316
0ea9281e 317class DNSPacket;
63347c6c 318uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
a6448d95 319// for SOA-EDIT
13f9e280
CH
320uint32_t calculateEditSOA(uint32_t old_serial, DNSSECKeeper& dk, const DNSName& zonename);
321uint32_t calculateEditSOA(uint32_t old_serial, const string& kind, const DNSName& zonename);
a6448d95 322// for SOA-EDIT-DNSUPDATE/API
13f9e280
CH
323bool increaseSOARecord(DNSResourceRecord& dr, const string& increaseKind, const string& editKind);
324bool makeIncreasedSOARecord(SOAData& sd, const string& increaseKind, const string& editKind, DNSResourceRecord& rrout);
5fff7d51 325DNSZoneRecord makeEditedDNSZRFromSOAData(DNSSECKeeper& dk, const SOAData& sd, DNSResourceRecord::Place place=DNSResourceRecord::ANSWER);