Changeset 1892

Show
Ignore:
Timestamp:
01/18/11 09:43:56 (2 years ago)
Author:
ahu
Message:

remove the signing code from dnspacket, where it was cute but wrong.

Location:
trunk/pdns/pdns
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/dnspacket.cc

    r1844 r1892  
    5959} 
    6060 
    61 const char *DNSPacket::getData(DNSSECKeeper* dk) 
     61const char *DNSPacket::getData() 
    6262{ 
    6363  if(!d_wrapped) 
    64     wrapup(dk); 
     64    wrapup(); 
    6565 
    6666  return stringbuffer.data(); 
     
    171171static int rrcomp(const DNSResourceRecord &A, const DNSResourceRecord &B) 
    172172{ 
    173   if(A.d_place<B.d_place) 
     173  if(A.d_place < B.d_place) 
    174174    return 1; 
    175175 
     
    224224} 
    225225 
     226 
    226227/** Must be called before attempting to access getData(). This function stuffs all resource 
    227228 *  records found in rrs into the data buffer. It also frees resource records queued for us. 
    228229 */ 
    229 void DNSPacket::wrapup(DNSSECKeeper* dk) 
     230void DNSPacket::wrapup() 
    230231{ 
    231232  if(d_wrapped) { 
     
    237238  vector<DNSResourceRecord>::iterator pos; 
    238239 
    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  
    245240  // we now need to order rrs so that the different sections come at the right place 
    246241  // we want a stable sort, based on the d_place field 
    247242 
    248   stable_sort(d_rrs.begin(),d_rrs.end(),rrcomp); 
     243  stable_sort(d_rrs.begin(),d_rrs.end(), rrcomp); 
    249244 
    250245  static bool mustShuffle =::arg().mustDo("no-shuffle"); 
     
    276271  if(!d_rrs.empty() || !opts.empty()) { 
    277272    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  
    284273      for(pos=d_rrs.begin(); pos < d_rrs.end(); ++pos) { 
    285274        // this needs to deal with the 'prio' mismatch: 
     
    293282        if(pos->content.empty())  // empty contents confuse the MOADNS setup 
    294283          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         
    310285        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));  
    312287        drc->toPacket(pw); 
    313288        if(!d_tcp && pw.size() + 20 > getMaxReplyLen()) { // 20 = room for EDNS0 
     
    321296        } 
    322297      } 
    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       
    327299 
    328300      if(!opts.empty() || d_dnssecOk) 
  • trunk/pdns/pdns/dnspacket.hh

    r1830 r1892  
    119119 
    120120  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 stringbuffer 
    122   const char *getData(DNSSECKeeper* dk=0); //!< get binary representation of packet, will call 'wrapup' for you 
     121  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 
    123123 
    124124  const char *getRaw(void); //!< provides access to the raw packet, possibly on a packet that has never been 'wrapped' 
     
    149149  bool d_tcp; 
    150150  bool d_dnssecOk; 
     151  vector<DNSResourceRecord>& getRRS() { return d_rrs; } 
    151152private: 
    152153  void pasteQ(const char *question, int length); //!< set the question of this packet, useful for crafting replies 
  • trunk/pdns/pdns/dnssecinfra.hh

    r1884 r1892  
    4343void fillOutRRSIG(DNSSECPrivateKey& dpk, const std::string& signQName, RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& toSign); 
    4444uint32_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,  
     45void 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); 
     47int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL,  
    4848                     vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent> &rrc, bool ksk); 
    4949 
    5050std::string hashQNameWithSalt(unsigned int times, const std::string& salt, const std::string& qname); 
    5151void decodeDERIntegerSequence(const std::string& input, vector<string>& output); 
    52  
     52class DNSPacket; 
     53void addRRSigs(DNSSECKeeper& dk, const std::string& signer, DNSPacket& p); 
    5354#endif 
  • trunk/pdns/pdns/dnssecsigner.cc

    r1867 r1892  
    2222#include "lock.hh" 
    2323 
    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  
    3724/* this is where the RRSIGs begin, key apex *name* gets found, keys are retrieved, 
    3825   but the actual signing happens in fillOutRRSIG */ 
    39 int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string signQName, uint16_t signQType, uint32_t signTTL,  
     26int getRRSIGsForRRSET(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, uint16_t signQType, uint32_t signTTL,  
    4027                     vector<shared_ptr<DNSRecordContent> >& toSign, vector<RRSIGRecordContent>& rrcs, bool ksk) 
    4128{ 
     
    4532  rrc.d_type=signQType; 
    4633 
    47   // d_algorithm gets filled out by getSignerAPEX, since only it looks up the key 
     34   
    4835  rrc.d_labels=countLabels(signQName);  
    4936  rrc.d_originalttl=signTTL;  
    5037  rrc.d_siginception=getCurrentInception();; 
    5138  rrc.d_sigexpire = rrc.d_siginception + 14*86400; // XXX should come from zone metadata 
     39  rrc.d_signer = signer; 
    5240  rrc.d_tag = 0; 
    5341   
    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 
    6043   
    6144  DNSSECKeeper::keyset_t keys = dk.getKeys(rrc.d_signer); 
     
    6649  // if ksk==0, get ZSKs, unless there is no ZSK, then get KSK 
    6750  BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type& keymeta, keys) { 
     51    rrc.d_algorithm = keymeta.first.d_algorithm; 
    6852    if(!keymeta.second.active)  
    6953      continue; 
     
    9175 
    9276// this is the entrypoint from DNSPacket 
    93 void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType,  
     77void addSignature(DNSSECKeeper& dk, const std::string& signer, const std::string signQName, const std::string& wildcardname, uint16_t signQType,  
    9478  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) 
    9680{ 
    9781  // cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n"; 
     
    10185    return; 
    10286 
    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) { 
    10488    // cerr<<"Error signing a record!"<<endl; 
    10589    return; 
    10690  } 
     91  DNSResourceRecord rr; 
     92  rr.qname=signQName; 
     93  rr.qtype=QType::RRSIG; 
     94  rr.ttl=signTTL; 
     95  rr.auth=false; 
     96   
    10797  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); 
    116100  } 
    117   pw.commit(); 
    118101 
    119102  toSign.clear(); 
     
    160143  g_signatures[lookup] = rrc.d_signature; 
    161144} 
     145 
     146static bool rrsigncomp(const DNSResourceRecord& a, const DNSResourceRecord& b) 
     147{ 
     148  return a.d_place < b.d_place; 
     149} 
     150 
     151void 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  
    998998    vector<RRSIGRecordContent> rrcs; 
    999999     
    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); 
    10011001    BOOST_FOREACH(RRSIGRecordContent& rrc, rrcs) { 
    10021002      rr.content=rrc.getZoneRepresentation(); 
     
    13471347    //    doDNSSECProcessing(p, r); 
    13481348 
    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 
    13501352    PC.insert(p, r); // in the packet cache 
    13511353  } 
  • trunk/pdns/pdns/tcpreceiver.cc

    r1888 r1892  
    176176void TCPNameserver::sendPacket(shared_ptr<DNSPacket> p, int outsock) 
    177177{ 
    178   DNSSECKeeper dk; 
    179   const char *buf=p->getData(&dk); 
     178  const char *buf=p->getData(); 
    180179  uint16_t len=htons(p->len); 
    181180  writenWithTimeout(outsock, &len, 2); 
     
    297296        cached->commitD(); // commit d to the packet                        inlined 
    298297 
    299         sendPacket(cached, fd); 
     298        sendPacket(cached, fd); // presigned, don't do it again 
    300299        S.inc("tcp-answers"); 
    301300        continue; 
     
    534533    if(!((++count)%chunk)) { 
    535534      count=0; 
    536      
     535      addRRSigs(dk, sd.qname, *outpacket); 
    537536      sendPacket(outpacket, outsock); 
    538537 
     
    596595   
    597596  if(count) { 
     597    addRRSigs(dk, sd.qname, *outpacket); 
    598598    sendPacket(outpacket, outsock); 
    599599  } 
     
    602602  /* and terminate with yet again the SOA record */ 
    603603  outpacket=shared_ptr<DNSPacket>(q->replyPacket()); 
    604   soa.priority=1234; 
     604   
     605  addRRSigs(dk, sd.qname, *outpacket); // don't sign the SOA! 
    605606  outpacket->addRecord(soa); 
    606607  sendPacket(outpacket, outsock);