Changeset 1892
- Timestamp:
- 01/18/11 09:43:56 (2 years ago)
- Location:
- trunk/pdns/pdns
- Files:
-
- 6 modified
-
dnspacket.cc (modified) (7 diffs)
-
dnspacket.hh (modified) (2 diffs)
-
dnssecinfra.hh (modified) (1 diff)
-
dnssecsigner.cc (modified) (6 diffs)
-
packethandler.cc (modified) (2 diffs)
-
tcpreceiver.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/pdns/pdns/dnspacket.cc
r1844 r1892 59 59 } 60 60 61 const char *DNSPacket::getData( DNSSECKeeper* dk)61 const char *DNSPacket::getData() 62 62 { 63 63 if(!d_wrapped) 64 wrapup( dk);64 wrapup(); 65 65 66 66 return stringbuffer.data(); … … 171 171 static int rrcomp(const DNSResourceRecord &A, const DNSResourceRecord &B) 172 172 { 173 if(A.d_place <B.d_place)173 if(A.d_place < B.d_place) 174 174 return 1; 175 175 … … 224 224 } 225 225 226 226 227 /** Must be called before attempting to access getData(). This function stuffs all resource 227 228 * records found in rrs into the data buffer. It also frees resource records queued for us. 228 229 */ 229 void DNSPacket::wrapup( DNSSECKeeper* dk)230 void DNSPacket::wrapup() 230 231 { 231 232 if(d_wrapped) { … … 237 238 vector<DNSResourceRecord>::iterator pos; 238 239 239 vector<DNSResourceRecord> additional;240 241 int ipos=d_rrs.size();242 d_rrs.resize(d_rrs.size()+additional.size());243 copy(additional.begin(), additional.end(), d_rrs.begin()+ipos);244 245 240 // we now need to order rrs so that the different sections come at the right place 246 241 // we want a stable sort, based on the d_place field 247 242 248 stable_sort(d_rrs.begin(),d_rrs.end(), rrcomp);243 stable_sort(d_rrs.begin(),d_rrs.end(), rrcomp); 249 244 250 245 static bool mustShuffle =::arg().mustDo("no-shuffle"); … … 276 271 if(!d_rrs.empty() || !opts.empty()) { 277 272 try { 278 string signQName, wildcardQName;279 uint16_t signQType=0;280 uint32_t signTTL=0;281 DNSPacketWriter::Place signPlace=DNSPacketWriter::ANSWER;282 vector<shared_ptr<DNSRecordContent> > toSign;283 284 273 for(pos=d_rrs.begin(); pos < d_rrs.end(); ++pos) { 285 274 // this needs to deal with the 'prio' mismatch: … … 293 282 if(pos->content.empty()) // empty contents confuse the MOADNS setup 294 283 pos->content="."; 295 shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(pos->qtype.getCode(), 1, pos->content)); 296 297 if(d_dnssecOk) { 298 if(pos != d_rrs.begin() && (signQType != pos->qtype.getCode() || signQName != pos->qname)) { 299 addSignature(*dk, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, d_tcp ? 0 : getMaxReplyLen(), pw); 300 } 301 signQName= pos->qname; 302 wildcardQName = pos->wildcardname; 303 signQType = pos ->qtype.getCode(); 304 signTTL = pos->ttl; 305 signPlace = (DNSPacketWriter::Place) pos->d_place; 306 if(pos->auth || pos->qtype.getCode() == QType::DS) 307 toSign.push_back(drc); 308 } 309 284 310 285 pw.startRecord(pos->qname, pos->qtype.getCode(), pos->ttl, pos->qclass, (DNSPacketWriter::Place)pos->d_place); 311 286 shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(pos->qtype.getCode(), 1, pos->content)); 312 287 drc->toPacket(pw); 313 288 if(!d_tcp && pw.size() + 20 > getMaxReplyLen()) { // 20 = room for EDNS0 … … 321 296 } 322 297 } 323 // I assume this is some dirty hack to prevent us from signing the last SOA record in an AXFR.. XXX FIXME 324 if(d_dnssecOk && !(d_tcp && d_rrs.rbegin()->qtype.getCode() == QType::SOA && d_rrs.rbegin()->priority == 1234)) { 325 addSignature(*dk, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, d_tcp ? 0 : getMaxReplyLen(), pw); 326 } 298 327 299 328 300 if(!opts.empty() || d_dnssecOk) -
trunk/pdns/pdns/dnspacket.hh
r1830 r1892 119 119 120 120 DTime d_dt; //!< the time this packet was created. replyPacket() copies this in for you, so d_dt becomes the time spent processing the question+answer 121 void wrapup( DNSSECKeeper* dk=0); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer122 const char *getData( DNSSECKeeper* dk=0); //!< get binary representation of packet, will call 'wrapup' for you121 void wrapup(); // writes out queued rrs, and generates the binary packet. also shuffles. also rectifies dnsheader 'd', and copies it to the stringbuffer 122 const char *getData(); //!< get binary representation of packet, will call 'wrapup' for you 123 123 124 124 const char *getRaw(void); //!< provides access to the raw packet, possibly on a packet that has never been 'wrapped' … … 149 149 bool d_tcp; 150 150 bool d_dnssecOk; 151 vector<DNSResourceRecord>& getRRS() { return d_rrs; } 151 152 private: 152 153 void pasteQ(const char *question, int length); //!< set the question of this packet, useful for crafting replies -
trunk/pdns/pdns/dnssecinfra.hh
r1884 r1892 43 43 void fillOutRRSIG(DNSSECPrivateKey& dpk, const std::string& signQName, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& toSign); 44 44 uint32_t getCurrentInception(); 45 void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign,46 uint16_t maxReplyLength, DNSPacketWriter& pw);47 int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string signQName, uint16_t signQType, uint32_t signTTL,45 void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, 46 vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSResourceRecord>& outsigned); 47 int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL, 48 48 vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent> &rrc, bool ksk); 49 49 50 50 std::string hashQNameWithSalt(unsigned int times, const std::string& salt, const std::string& qname); 51 51 void decodeDERIntegerSequence(const std::string& input, vector<string>& output); 52 52 class DNSPacket; 53 void addRRSigs(DNSSECKeeper& dk, const std::string& signer, DNSPacket& p); 53 54 #endif -
trunk/pdns/pdns/dnssecsigner.cc
r1867 r1892 22 22 #include "lock.hh" 23 23 24 // nobody should ever call this function, you know the SOA/auth already!25 bool getSignerApexFor(DNSSECKeeper& dk, const std::string& qname, std::string &signer)26 {27 // cerr<<"getSignerApexFor: called, and should not be, should go away!"<<endl;28 signer=qname;29 do {30 if(dk.haveActiveKSKFor(signer)) {31 return true;32 }33 } while(chopOff(signer));34 return false;35 }36 37 24 /* this is where the RRSIGs begin, key apex *name* gets found, keys are retrieved, 38 25 but the actual signing happens in fillOutRRSIG */ 39 int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string signQName, uint16_t signQType, uint32_t signTTL,26 int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL, 40 27 vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs, bool ksk) 41 28 { … … 45 32 rrc.d_type=signQType; 46 33 47 // d_algorithm gets filled out by getSignerAPEX, since only it looks up the key34 48 35 rrc.d_labels=countLabels(signQName); 49 36 rrc.d_originalttl=signTTL; 50 37 rrc.d_siginception=getCurrentInception();; 51 38 rrc.d_sigexpire = rrc.d_siginception + 14*86400; // XXX should come from zone metadata 39 rrc.d_signer = signer; 52 40 rrc.d_tag = 0; 53 41 54 // XXX we know the apex already.. is is the SOA name which we determined earlier 55 if(!getSignerApexFor(dk, signQName, rrc.d_signer)) { // this is the cutout for signing non-dnssec enabled zones 56 // cerr<<"No signer known for '"<<signQName<<"'\n"; 57 return -1; 58 } 59 // we sign the RRSET in toSign + the rrc w/o key 42 // we sign the RRSET in toSign + the rrc w/o hash 60 43 61 44 DNSSECKeeper::keyset_t keys = dk.getKeys(rrc.d_signer); … … 66 49 // if ksk==0, get ZSKs, unless there is no ZSK, then get KSK 67 50 BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type& keymeta, keys) { 51 rrc.d_algorithm = keymeta.first.d_algorithm; 68 52 if(!keymeta.second.active) 69 53 continue; … … 91 75 92 76 // this is the entrypoint from DNSPacket 93 void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType,77 void addSignature(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, const std::string& wildcardname, uint16_t signQType, 94 78 uint32_t signTTL, DNSPacketWriter::Place signPlace, 95 vector<shared_ptr<DNSRecordContent> >& toSign, uint16_t maxReplyLen, DNSPacketWriter& pw)79 vector<shared_ptr<DNSRecordContent> >& toSign, vector<DNSResourceRecord>& outsigned) 96 80 { 97 81 // cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n"; … … 101 85 return; 102 86 103 if(getRRSIGsForRRSET(dk, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) {87 if(getRRSIGsForRRSET(dk, signer, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) { 104 88 // cerr<<"Error signing a record!"<<endl; 105 89 return; 106 90 } 91 DNSResourceRecord rr; 92 rr.qname=signQName; 93 rr.qtype=QType::RRSIG; 94 rr.ttl=signTTL; 95 rr.auth=false; 96 107 97 BOOST_FOREACH(RRSIGRecordContent& rrc, rrcs) { 108 pw.startRecord(signQName, QType::RRSIG, signTTL, 1, 109 signQType==QType::DNSKEY ? DNSPacketWriter:: ANSWER : signPlace); 110 rrc.toPacket(pw); 111 if(maxReplyLen && (pw.size() + 20) > maxReplyLen) { 112 pw.rollback(); 113 pw.getHeader()->tc=1; 114 return; 115 } 98 rr.content = rrc.getZoneRepresentation(); 99 outsigned.push_back(rr); 116 100 } 117 pw.commit();118 101 119 102 toSign.clear(); … … 160 143 g_signatures[lookup] = rrc.d_signature; 161 144 } 145 146 static bool rrsigncomp(const DNSResourceRecord& a, const DNSResourceRecord& b) 147 { 148 return a.d_place < b.d_place; 149 } 150 151 void addRRSigs(DNSSECKeeper& dk, const std::string& signer, DNSPacket& p) 152 { 153 vector<DNSResourceRecord>& rrs=p.getRRS(); 154 155 stable_sort(rrs.begin(), rrs.end(), rrsigncomp); 156 157 string signQName, wildcardQName; 158 uint16_t signQType=0; 159 uint32_t signTTL=0; 160 161 DNSPacketWriter::Place signPlace=DNSPacketWriter::ANSWER; 162 vector<shared_ptr<DNSRecordContent> > toSign; 163 164 vector<DNSResourceRecord> signedRecords; 165 166 for(vector<DNSResourceRecord>::const_iterator pos = rrs.begin(); pos != rrs.end(); ++pos) { 167 signedRecords.push_back(*pos); 168 if(pos != rrs.begin() && (signQType != pos->qtype.getCode() || signQName != pos->qname)) { 169 addSignature(dk, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords); 170 } 171 signQName= pos->qname; 172 wildcardQName = pos->wildcardname; 173 signQType = pos ->qtype.getCode(); 174 signTTL = pos->ttl; 175 signPlace = (DNSPacketWriter::Place) pos->d_place; 176 if(pos->auth || pos->qtype.getCode() == QType::DS) { 177 string content = pos ->content; 178 if(pos->qtype.getCode()==QType::MX || pos->qtype.getCode() == QType::SRV) { 179 content = lexical_cast<string>(pos->priority) + " " + pos->content; 180 } 181 if(!pos->content.empty() && pos->qtype.getCode()==QType::TXT && pos->content[0]!='"') { 182 content="\""+pos->content+"\""; 183 } 184 if(pos->content.empty()) // empty contents confuse the MOADNS setup 185 content="."; 186 187 shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(pos->qtype.getCode(), 1, content)); 188 toSign.push_back(drc); 189 } 190 } 191 addSignature(dk, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords); 192 193 rrs.swap(signedRecords); 194 } -
trunk/pdns/pdns/packethandler.cc
r1886 r1892 998 998 vector<RRSIGRecordContent> rrcs; 999 999 1000 getRRSIGsForRRSET(d_dk, p->qdomain, iter.first, 3600, iter.second, rrcs, iter.first == QType::DNSKEY);1000 getRRSIGsForRRSET(d_dk, sd.qname, p->qdomain, iter.first, 3600, iter.second, rrcs, iter.first == QType::DNSKEY); 1001 1001 BOOST_FOREACH(RRSIGRecordContent& rrc, rrcs) { 1002 1002 rr.content=rrc.getZoneRepresentation(); … … 1347 1347 // doDNSSECProcessing(p, r); 1348 1348 1349 r->wrapup(&d_dk); // needed for inserting in cache 1349 if(p->d_dnssecOk) 1350 addRRSigs(d_dk, sd.qname, *r); 1351 r->wrapup(); // needed for inserting in cache 1350 1352 PC.insert(p, r); // in the packet cache 1351 1353 } -
trunk/pdns/pdns/tcpreceiver.cc
r1888 r1892 176 176 void TCPNameserver::sendPacket(shared_ptr<DNSPacket> p, int outsock) 177 177 { 178 DNSSECKeeper dk; 179 const char *buf=p->getData(&dk); 178 const char *buf=p->getData(); 180 179 uint16_t len=htons(p->len); 181 180 writenWithTimeout(outsock, &len, 2); … … 297 296 cached->commitD(); // commit d to the packet inlined 298 297 299 sendPacket(cached, fd); 298 sendPacket(cached, fd); // presigned, don't do it again 300 299 S.inc("tcp-answers"); 301 300 continue; … … 534 533 if(!((++count)%chunk)) { 535 534 count=0; 536 535 addRRSigs(dk, sd.qname, *outpacket); 537 536 sendPacket(outpacket, outsock); 538 537 … … 596 595 597 596 if(count) { 597 addRRSigs(dk, sd.qname, *outpacket); 598 598 sendPacket(outpacket, outsock); 599 599 } … … 602 602 /* and terminate with yet again the SOA record */ 603 603 outpacket=shared_ptr<DNSPacket>(q->replyPacket()); 604 soa.priority=1234; 604 605 addRRSigs(dk, sd.qname, *outpacket); // don't sign the SOA! 605 606 outpacket->addRecord(soa); 606 607 sendPacket(outpacket, outsock);