]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/dnsseckeeper.hh
Merge pull request #5937 from rgacogne/rec-self-resolving-ns
[thirdparty/pdns.git] / pdns / dnsseckeeper.hh
1 /*
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
23 #include <string>
24 #include <string.h>
25 #include <vector>
26 #include <boost/logic/tribool.hpp>
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>
32 #include "dnssecinfra.hh"
33 #include "dnsrecords.hh"
34 #include "ueberbackend.hh"
35
36 using namespace ::boost::multi_index;
37
38 class DNSSECKeeper : public boost::noncopyable
39 {
40 public:
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,
54 ED25519=15,
55 ED448=16
56 };
57
58 enum dsdigestalgorithm_t : uint8_t {
59 SHA1=1,
60 SHA256=2,
61 GOST=3,
62 SHA384=4
63 };
64
65 struct KeyMetaData
66 {
67 string fname;
68 unsigned int id;
69 bool active;
70 keytype_t keyType;
71 bool hasSEPBit;
72 };
73 typedef std::pair<DNSSECPrivateKey, KeyMetaData> keymeta_t;
74 typedef std::vector<keymeta_t > keyset_t;
75
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
90 static int shorthand2algorithm(const string &algorithm)
91 {
92 if (!algorithm.compare("rsamd5")) return RSAMD5;
93 if (!algorithm.compare("dh")) return DH;
94 if (!algorithm.compare("dsa")) return DSA;
95 if (!algorithm.compare("rsasha1")) return RSASHA1;
96 if (!algorithm.compare("rsasha256")) return RSASHA256;
97 if (!algorithm.compare("rsasha512")) return RSASHA512;
98 if (!algorithm.compare("ecc-gost")) return ECCGOST;
99 if (!algorithm.compare("gost")) return ECCGOST;
100 if (!algorithm.compare("ecdsa256")) return ECDSA256;
101 if (!algorithm.compare("ecdsa384")) return ECDSA384;
102 if (!algorithm.compare("ed25519")) return ED25519;
103 if (!algorithm.compare("ed448")) return ED448;
104 return -1;
105 }
106
107 static string algorithm2name(uint8_t algo) {
108 switch(algo) {
109 case 0:
110 case 4:
111 case 9:
112 case 11:
113 return "Reserved";
114 case RSAMD5:
115 return "RSAMD5";
116 case DH:
117 return "DH";
118 case DSA:
119 return "DSA";
120 case RSASHA1:
121 return "RSASHA1";
122 case DSANSEC3SHA1:
123 return "DSA-NSEC3-SHA1";
124 case RSASHA1NSEC3SHA1:
125 return "RSASHA1-NSEC3-SHA1";
126 case RSASHA256:
127 return "RSASHA256";
128 case RSASHA512:
129 return "RSASHA512";
130 case ECCGOST:
131 return "ECC-GOST";
132 case ECDSA256:
133 return "ECDSAP256SHA256";
134 case ECDSA384:
135 return "ECDSAP384SHA384";
136 case ED25519:
137 return "ED25519";
138 case ED448:
139 return "ED448";
140 case 252:
141 return "INDIRECT";
142 case 253:
143 return "PRIVATEDNS";
144 case 254:
145 return "PRIVATEOID";
146 default:
147 return "Unallocated/Reserved";
148 }
149 }
150
151 private:
152 UeberBackend* d_keymetadb;
153 bool d_ourDB;
154
155 public:
156 DNSSECKeeper() : d_keymetadb( new UeberBackend("key-only")), d_ourDB(true)
157 {
158
159 }
160
161 DNSSECKeeper(UeberBackend* db) : d_keymetadb(db), d_ourDB(false)
162 {
163 }
164
165 ~DNSSECKeeper()
166 {
167 if(d_ourDB)
168 delete d_keymetadb;
169 }
170 bool doesDNSSEC();
171 bool isSecuredZone(const DNSName& zone);
172 static uint64_t dbdnssecCacheSizes(const std::string& str);
173 keyset_t getEntryPoints(const DNSName& zname);
174 keyset_t getKeys(const DNSName& zone, bool useCache = true);
175 DNSSECPrivateKey getKeyById(const DNSName& zone, unsigned int id);
176 bool addKey(const DNSName& zname, bool setSEPBit, int algorithm, int64_t& id, int bits=0, bool active=true);
177 bool addKey(const DNSName& zname, const DNSSECPrivateKey& dpk, int64_t& id, bool active=true);
178 bool removeKey(const DNSName& zname, unsigned int id);
179 bool activateKey(const DNSName& zname, unsigned int id);
180 bool deactivateKey(const DNSName& zname, unsigned int id);
181 bool checkKeys(const DNSName& zname);
182
183 bool getNSEC3PARAM(const DNSName& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
184 bool checkNSEC3PARAM(const NSEC3PARAMRecordContent& ns3p, string& msg);
185 bool setNSEC3PARAM(const DNSName& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
186 bool unsetNSEC3PARAM(const DNSName& zname);
187 void clearAllCaches();
188 void clearCaches(const DNSName& name);
189 bool getPreRRSIGs(UeberBackend& db, const DNSName& signer, const DNSName& qname, const DNSName& wildcardname, const QType& qtype, DNSResourceRecord::Place, vector<DNSZoneRecord>& rrsigs, uint32_t signTTL);
190 bool isPresigned(const DNSName& zname);
191 bool setPresigned(const DNSName& zname);
192 bool unsetPresigned(const DNSName& zname);
193 bool setPublishCDNSKEY(const DNSName& zname);
194 bool unsetPublishCDNSKEY(const DNSName& zname);
195 bool setPublishCDS(const DNSName& zname, const string& digestAlgos);
196 bool unsetPublishCDS(const DNSName& zname);
197
198 bool TSIGGrantsAccess(const DNSName& zone, const DNSName& keyname);
199 bool getTSIGForAccess(const DNSName& zone, const string& master, DNSName* keyname);
200
201 void startTransaction(const DNSName& zone, int zone_id)
202 {
203 (*d_keymetadb->backends.begin())->startTransaction(zone, zone_id);
204 }
205
206 void commitTransaction()
207 {
208 (*d_keymetadb->backends.begin())->commitTransaction();
209 }
210
211 void getFromMeta(const DNSName& zname, const std::string& key, std::string& value);
212 void getSoaEdit(const DNSName& zname, std::string& value);
213 bool rectifyZone(const DNSName& zone, std::string& error, std::string& info, bool doTransaction);
214 private:
215
216
217 struct KeyCacheEntry
218 {
219 typedef vector<DNSSECKeeper::keymeta_t> keys_t;
220
221 uint32_t getTTD() const
222 {
223 return d_ttd;
224 }
225
226 DNSName d_domain;
227 mutable keys_t d_keys;
228 unsigned int d_ttd;
229 };
230
231 struct METACacheEntry
232 {
233 uint32_t getTTD() const
234 {
235 return d_ttd;
236 }
237
238 DNSName d_domain;
239 mutable std::string d_key, d_value;
240 unsigned int d_ttd;
241
242 };
243
244
245 typedef multi_index_container<
246 KeyCacheEntry,
247 indexed_by<
248 ordered_unique<member<KeyCacheEntry, DNSName, &KeyCacheEntry::d_domain> >,
249 sequenced<>
250 >
251 > keycache_t;
252 typedef multi_index_container<
253 METACacheEntry,
254 indexed_by<
255 ordered_unique<
256 composite_key<
257 METACacheEntry,
258 member<METACacheEntry, DNSName, &METACacheEntry::d_domain> ,
259 member<METACacheEntry, std::string, &METACacheEntry::d_key>
260 >, composite_key_compare<std::less<DNSName>, CIStringCompare> >,
261 sequenced<>
262 >
263 > metacache_t;
264
265 void cleanup();
266
267 static keycache_t s_keycache;
268 static metacache_t s_metacache;
269 static pthread_rwlock_t s_metacachelock;
270 static pthread_rwlock_t s_keycachelock;
271 static AtomicCounter s_ops;
272 static time_t s_last_prune;
273
274 public:
275 void preRemoval(const KeyCacheEntry&)
276 {
277 }
278 void preRemoval(const METACacheEntry&)
279 {
280 }
281 };
282
283 class DNSPacket;
284 uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq);
285 // for SOA-EDIT
286 uint32_t calculateEditSOA(const DNSZoneRecord& rr, const string& kind);
287 uint32_t calculateEditSOA(const SOAData& sd, const string& kind);
288 bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp);
289 bool editSOARecord(DNSZoneRecord& rr, const string& kind);
290 // for SOA-EDIT-DNSUPDATE/API
291 uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind);
292 bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind);
293 bool increaseSOARecord(DNSZoneRecord& rr, const string& increaseKind, const string& editKind);