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