Changeset 1790

Show
Ignore:
Timestamp:
01/02/11 19:34:10 (2 years ago)
Author:
ahu
Message:

move around a lot of stuff to isolate dnssec db connectivity
fix up addDomainMetadata so it doesn't keep on adding
add import-zone-key functionality to dbdnsseckeeper
remove key-repository setting from loads of places

Location:
trunk/pdns/pdns
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/Makefile.am

    r1782 r1790  
    4545aes/aestab.c aes/aestab.h aes/brg_endian.h aes/brg_types.h aes/dns_random.cc \ 
    4646randomhelper.cc namespaces.hh nsecrecords.cc base32.cc dbdnsseckeeper.cc dnssecinfra.cc \ 
    47 dnsseckeeper.hh dnssecinfra.hh base32.hh 
     47dnsseckeeper.hh dnssecinfra.hh base32.hh dns.cc 
    4848 
    4949# 
     
    6161        backends/gsql/gsqlbackend.cc \ 
    6262        backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh zoneparser-tng.cc \ 
    63         dynlistener.cc 
     63        dynlistener.cc dns.cc 
    6464 
    6565pdnssec_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ -Lext/polarssl/library/  
  • trunk/pdns/pdns/backends/gsql/gsqlbackend.cc

    r1781 r1790  
    2020#include <sstream> 
    2121#include <boost/foreach.hpp> 
     22#include <boost/format.hpp> 
    2223using namespace boost; 
    2324 
     
    248249   
    249250  d_GetDomainMetadataQuery = "select content from domains, domainmetadata where domain_id=domains.id and name='%s' and domainmetadata.kind='%s'"; 
     251  d_ClearDomainMetadataQuery = "delete from domainmetadata where domain_id=(select id from domains where name='%s') and domainmetadata.kind='%s'"; 
    250252  d_SetDomainMetadataQuery = "insert into domainmetadata (domain_id, kind, content) select id, '%s', '%s' from domains where name='%s'"; 
    251253} 
     
    379381{ 
    380382  char output[16384];   
    381   snprintf(output,sizeof(output)-1,d_SetDomainMetadataQuery.c_str(), 
    382            sqlEscape(kind).c_str(), sqlEscape(*meta.begin()).c_str(), sqlEscape(name).c_str()); 
    383  
    384   try { 
    385     d_db->doCommand(output); 
     383 
     384  if(!meta.empty()) 
     385    snprintf(output,sizeof(output)-1,d_SetDomainMetadataQuery.c_str(), 
     386      sqlEscape(kind).c_str(), sqlEscape(*meta.begin()).c_str(), sqlEscape(name).c_str()); 
     387 
     388  string clearQuery = (boost::format(d_ClearDomainMetadataQuery) % sqlEscape(name) % sqlEscape(kind)).str(); 
     389 
     390  try { 
     391    d_db->doCommand(clearQuery); 
     392    if(!meta.empty()) 
     393      d_db->doCommand(output); 
    386394  } 
    387395  catch (SSqlException &e) { 
    388396    throw AhuException("GSQLBackend unable to store metadata key: "+e.txtReason()); 
    389397  } 
     398   
    390399  return true; 
    391400} 
  • trunk/pdns/pdns/backends/gsql/gsqlbackend.hh

    r1781 r1790  
    8585  string d_ListDomainKeysQuery; 
    8686  string d_GetDomainMetadataQuery; 
     87  string d_ClearDomainMetadataQuery; 
    8788  string d_SetDomainMetadataQuery; 
    8889protected:   
  • trunk/pdns/pdns/common_startup.cc

    r1763 r1790  
    100100  ::arg().set("webserver-port","Port of webserver to listen on")="8081"; 
    101101  ::arg().set("webserver-password","Password required for accessing the webserver")=""; 
    102   ::arg().set("key-repository", "Where DNSSEC keying material lives")="./keys"; 
    103102 
    104103  ::arg().setSwitch("out-of-zone-additional-processing","Do out of zone additional processing")="yes"; 
  • trunk/pdns/pdns/dbdnsseckeeper.cc

    r1781 r1790  
    3838  DNSSECPrivateKey dpk; 
    3939  dpk.d_key.create(bits);  
    40   
     40  addKey(name, keyOrZone, dpk, active); 
     41} 
     42 
     43void DNSSECKeeper::addKey(const std::string& name, bool keyOrZone, const DNSSECPrivateKey& dpk, bool active) 
     44{ 
    4145  DNSBackend::KeyData kd; 
    4246  kd.flags = 256 + keyOrZone; 
    4347  kd.active = active; 
    44   kd.content = dpk.d_key.convertToISC(algorithm); 
     48  kd.content = dpk.d_key.convertToISC(5); 
    4549  
    4650 // now store it 
     
    8084  } 
    8185  throw runtime_error("Can't find a key with id "+lexical_cast<string>(id)+" for zone '"+zname+"'"); 
    82    
    83    
    8486} 
    8587 
     
    130132  UeberBackend db; 
    131133  db.setDomainMetadata(zname, "NSEC3PARAM", meta); 
    132    
    133   // XXX do db 
    134134} 
    135135 
    136136void DNSSECKeeper::unsetNSEC3PARAM(const std::string& zname) 
    137137{ 
    138   // XXX do db 
     138  UeberBackend db; 
     139  db.setDomainMetadata(zname, "NSEC3PARAM", vector<string>()); 
    139140} 
    140141 
     
    175176} 
    176177  
    177  
     178bool getSignerFor(const std::string& qname, std::string &signer) 
     179{ 
     180  DNSSECKeeper dk; 
     181 
     182  signer=qname; 
     183  do { 
     184    if(dk.haveActiveKSKFor(signer))  
     185      return true; 
     186  } while(chopOff(signer)); 
     187  return false; 
     188} 
     189 
     190DNSKEYRecordContent getDNSKEYFor(const std::string& qname, bool withKSK, RSAContext* rc) 
     191{ 
     192  DNSSECKeeper dk; 
     193  cerr<<"Asked for a DNSKEY for '"<<qname<<"', withKSK="<<withKSK<<"\n"; 
     194  DNSSECPrivateKey dpk; 
     195 
     196  if(!withKSK) { 
     197    DNSSECKeeper::keyset_t zskset=dk.getKeys(qname, false); 
     198    BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type value, zskset) { 
     199      if(value.second.active) { 
     200        cerr<<"Found a ZSK for '"<<qname<<"', key tag = "<<value.first.getDNSKEY().getTag()<<endl; 
     201        *rc=value.first.d_key; 
     202        return value.first.getDNSKEY(); 
     203      } 
     204      else  
     205        cerr<<"Found an inactive ZSK for '"<<qname<<"', key tag = "<<value.first.getDNSKEY().getTag()<<endl; 
     206    } 
     207    cerr<<"Could not find an active ZSK for '"<<qname<<"'"<<endl; 
     208    exit(1); 
     209  } 
     210  else if(dk.haveActiveKSKFor(qname, &dpk)) { 
     211    cerr<<"Found a KSK for '"<<qname<<"'"<<endl; 
     212    *rc=dpk.d_key; 
     213    return dpk.getDNSKEY(); 
     214  } else { 
     215      cerr<<"DID NOT FIND A ZSK for '"<<qname<<"'"<<endl; 
     216      exit(1); 
     217  } 
     218} 
     219 
     220int getRRSIGForRRSET(const std::string signQName, uint16_t signQType, uint32_t signTTL,  
     221                     vector<shared_ptr<DNSRecordContent> >& toSign, RRSIGRecordContent& rrc, bool ksk) 
     222{ 
     223  if(toSign.empty()) 
     224    return -1; 
     225 
     226  rrc.d_type=signQType; 
     227 
     228  // d_algorithm gets filled out by fillOutRRSIG, since it  gets the key 
     229  rrc.d_labels=countLabels(signQName);  
     230  rrc.d_originalttl=signTTL;  
     231  rrc.d_siginception=getCurrentInception();; 
     232  rrc.d_sigexpire = rrc.d_siginception + 14*86400; 
     233 
     234  rrc.d_tag=0; 
     235  if(!getSignerFor(signQName, rrc.d_signer)) { 
     236    cerr<<"No signer known for '"<<signQName<<"'\n"; 
     237    return -1; 
     238  } 
     239     
     240  string hash= getSHA1HashForRRSET(signQName,  rrc, toSign); 
     241  fillOutRRSIG(signQName, rrc, hash, toSign, ksk); 
     242  return 0; 
     243} 
     244 
     245void addSignature(const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign, DNSPacketWriter& pw) 
     246{ 
     247  // cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n"; 
     248 
     249  RRSIGRecordContent rrc; 
     250  if(toSign.empty()) 
     251    return; 
     252 
     253  for(int ksk = 0; ksk < 2; ++ksk) { 
     254    if(getRRSIGForRRSET(wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrc, ksk) < 0) { 
     255      cerr<<"Error signing a record!"<<endl; 
     256      return; 
     257    } 
     258     
     259    pw.startRecord(signQName, QType::RRSIG, 3600, 1,  
     260                   signQType==QType::DNSKEY ? DNSPacketWriter:: ANSWER : signPlace);  
     261    rrc.toPacket(pw); 
     262     
     263    pw.commit(); 
     264    if(signQType != QType::DNSKEY) 
     265      break; 
     266  } 
     267 
     268  toSign.clear(); 
     269} 
     270 
     271// XXXX FIXME THINK ABOUT LOCKING HERE 
     272map<pair<string, uint16_t>, RRSIGRecordContent> g_rrsigs; 
     273 
     274void fillOutRRSIG(const std::string& signQName, RRSIGRecordContent& rrc, const std::string& hash, vector<shared_ptr<DNSRecordContent> >& toSign, bool withKSK)  
     275{ 
     276  RSAContext rc; 
     277 
     278  DNSKEYRecordContent drc=getDNSKEYFor(rrc.d_signer, withKSK, &rc); 
     279  rrc.d_tag = drc.getTag(); 
     280  rrc.d_algorithm = drc.d_algorithm; 
     281   
     282  if(g_rrsigs.count(make_pair(hash, rrc.d_tag))) { 
     283    // cerr<<"RRSIG cache hit !"<<endl; 
     284    rrc = g_rrsigs[make_pair(hash, rrc.d_tag)]; 
     285    return; 
     286  } 
     287     
     288  string realhash=getSHA1HashForRRSET(signQName, rrc, toSign); 
     289 
     290  unsigned char signature[mpi_size(&rc.getContext().N)]; 
     291 
     292  int ret=rsa_pkcs1_sign(&rc.getContext(), RSA_PRIVATE, SIG_RSA_SHA1, 20, (unsigned char*) realhash.c_str(), signature); 
     293   
     294  if(ret!=0) { 
     295    cerr<<"signing returned: "<<ret<<endl; 
     296    exit(1); 
     297  } 
     298   
     299  rrc.d_signature.assign((char*)signature, sizeof(signature)); 
     300   
     301  g_rrsigs[make_pair(hash, rrc.d_tag)] = rrc; 
     302 
     303} 
  • trunk/pdns/pdns/dnssecinfra.cc

    r1785 r1790  
    3636} 
    3737 
    38 std::string RSAContext::convertToISC(unsigned int algorithm) 
     38std::string RSAContext::convertToISC(unsigned int algorithm) const 
    3939{ 
    4040  string ret; 
    41   typedef vector<pair<string, mpi*> > outputs_t; 
     41  typedef vector<pair<string, const mpi*> > outputs_t; 
    4242  outputs_t outputs; 
    4343  push_back(outputs)("Modulus", &d_context.N)("PublicExponent",&d_context.E) 
     
    293293} 
    294294 
    295 bool getSignerFor(const std::string& keyRepositoryDir, const std::string& qname, std::string &signer) 
    296 { 
    297   DNSSECKeeper dk(keyRepositoryDir);  
    298  
    299   signer=qname; 
    300   do { 
    301     if(dk.haveActiveKSKFor(signer))  
    302       return true; 
    303   } while(chopOff(signer)); 
    304   return false; 
    305 } 
    306295 
    307296int countLabels(const std::string& signQName) 
     
    319308 
    320309 
    321 DNSKEYRecordContent getDNSKEYFor(const std::string& keyRepositoryDir, const std::string& qname, bool withKSK, RSAContext* rc) 
    322 { 
    323   DNSSECKeeper dk(keyRepositoryDir); 
    324   cerr<<"Asked for a DNSKEY for '"<<qname<<"', withKSK="<<withKSK<<"\n"; 
    325   DNSSECPrivateKey dpk; 
    326  
    327   if(!withKSK) { 
    328     DNSSECKeeper::keyset_t zskset=dk.getKeys(qname, false); 
    329     BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type value, zskset) { 
    330       if(value.second.active) { 
    331         cerr<<"Found a ZSK for '"<<qname<<"', key tag = "<<value.first.getDNSKEY().getTag()<<endl; 
    332         *rc=value.first.d_key; 
    333         return value.first.getDNSKEY(); 
    334       } 
    335       else  
    336         cerr<<"Found an inactive ZSK for '"<<qname<<"', key tag = "<<value.first.getDNSKEY().getTag()<<endl; 
    337     } 
    338     cerr<<"Could not find an active ZSK for '"<<qname<<"'"<<endl; 
    339     exit(1); 
    340   } 
    341   else if(dk.haveActiveKSKFor(qname, &dpk)) { 
    342     cerr<<"Found a KSK for '"<<qname<<"'"<<endl; 
    343     *rc=dpk.d_key; 
    344     return dpk.getDNSKEY(); 
    345   } else { 
    346       cerr<<"DID NOT FIND A ZSK for '"<<qname<<"'"<<endl; 
    347       exit(1); 
    348   } 
    349 } 
    350  
    351 // XXXX FIXME THINK ABOUT LOCKING HERE 
    352 map<pair<string, uint16_t>, RRSIGRecordContent> g_rrsigs; 
    353  
    354 void fillOutRRSIG(const std::string& keyrepodir, const std::string& signQName, RRSIGRecordContent& rrc, const std::string& hash, vector<shared_ptr<DNSRecordContent> >& toSign, bool withKSK)  
    355 { 
    356   RSAContext rc; 
    357  
    358   DNSKEYRecordContent drc =getDNSKEYFor(keyrepodir, rrc.d_signer, withKSK, &rc); 
    359   rrc.d_tag = drc.getTag(); 
    360   rrc.d_algorithm = drc.d_algorithm; 
    361    
    362   if(g_rrsigs.count(make_pair(hash, rrc.d_tag))) { 
    363     // cerr<<"RRSIG cache hit !"<<endl; 
    364     rrc = g_rrsigs[make_pair(hash, rrc.d_tag)]; 
    365     return; 
    366   } 
    367      
    368   string realhash=getSHA1HashForRRSET(signQName, rrc, toSign); 
    369  
    370   unsigned char signature[mpi_size(&rc.getContext().N)]; 
    371  
    372   int ret=rsa_pkcs1_sign(&rc.getContext(), RSA_PRIVATE, SIG_RSA_SHA1, 20, (unsigned char*) realhash.c_str(), signature); 
    373    
    374   if(ret!=0) { 
    375     cerr<<"signing returned: "<<ret<<endl; 
    376     exit(1); 
    377   } 
    378    
    379   rrc.d_signature.assign((char*)signature, sizeof(signature)); 
    380    
    381   g_rrsigs[make_pair(hash, rrc.d_tag)] = rrc; 
    382  
    383 } 
    384  
    385310uint32_t getCurrentInception() 
    386311{ 
     
    390315} 
    391316 
    392  
    393 int getRRSIGForRRSET(const std::string& keyrepodir, const std::string signQName, uint16_t signQType, uint32_t signTTL,  
    394                      vector<shared_ptr<DNSRecordContent> >& toSign, RRSIGRecordContent& rrc, bool ksk) 
    395 { 
    396   if(toSign.empty()) 
    397     return -1; 
    398  
    399   rrc.d_type=signQType; 
    400  
    401   // d_algorithm gets filled out by fillOutRRSIG, since it  gets the key 
    402   rrc.d_labels=countLabels(signQName);  
    403   rrc.d_originalttl=signTTL;  
    404   rrc.d_siginception=getCurrentInception();; 
    405   rrc.d_sigexpire = rrc.d_siginception + 14*86400; 
    406  
    407   rrc.d_tag=0; 
    408   if(!getSignerFor(keyrepodir, signQName, rrc.d_signer)) { 
    409     cerr<<"No signer known for '"<<signQName<<"'\n"; 
    410     return -1; 
    411   } 
    412      
    413   string hash= getSHA1HashForRRSET(signQName,  rrc, toSign); 
    414   fillOutRRSIG(keyrepodir, signQName, rrc, hash, toSign, ksk); 
    415   return 0; 
    416 } 
    417  
    418 void addSignature(const std::string& keyrepodir, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign, DNSPacketWriter& pw) 
    419 { 
    420   // cerr<<"Asked to sign '"<<signQName<<"'|"<<DNSRecordContent::NumberToType(signQType)<<", "<<toSign.size()<<" records\n"; 
    421  
    422   RRSIGRecordContent rrc; 
    423   if(toSign.empty()) 
    424     return; 
    425  
    426   for(int ksk = 0; ksk < 2; ++ksk) { 
    427     if(getRRSIGForRRSET(keyrepodir, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrc, ksk) < 0) { 
    428       cerr<<"Error signing a record!"<<endl; 
    429       return; 
    430     } 
    431      
    432     pw.startRecord(signQName, QType::RRSIG, 3600, 1,  
    433                    signQType==QType::DNSKEY ? DNSPacketWriter:: ANSWER : signPlace);  
    434     rrc.toPacket(pw); 
    435      
    436     pw.commit(); 
    437     if(signQType != QType::DNSKEY) 
    438       break; 
    439   } 
    440  
    441   toSign.clear(); 
    442 } 
    443317 
    444318 
  • trunk/pdns/pdns/dnssecinfra.hh

    r1785 r1790  
    3838 
    3939DNSKEYRecordContent getDNSKEYFor(const std::string& keyrepodir, const std::string& qname, bool withKSK, RSAContext* rc); 
    40 void fillOutRRSIG(const std::string& keyrepodir, const std::string& signQName, RRSIGRecordContent& rrc, const std::string& hash, vector<shared_ptr<DNSRecordContent> >& toSign, bool withKSK=false); 
     40void fillOutRRSIG(const std::string& signQName, RRSIGRecordContent& rrc, const std::string& hash, vector<shared_ptr<DNSRecordContent> >& toSign, bool withKSK=false); 
    4141uint32_t getCurrentInception(); 
    42 void addSignature(const std::string& keyrepodir, const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign, DNSPacketWriter& pw); 
    43 int getRRSIGForRRSET(const std::string& keyrepodir, const std::string signQName, uint16_t signQType, uint32_t signTTL,  
     42void addSignature(const std::string signQName, const std::string& wildcardname, uint16_t signQType, uint32_t signTTL, DNSPacketWriter::Place signPlace, vector<shared_ptr<DNSRecordContent> >& toSign, DNSPacketWriter& pw); 
     43int getRRSIGForRRSET(const std::string signQName, uint16_t signQType, uint32_t signTTL,  
    4444                     vector<shared_ptr<DNSRecordContent> >& toSign, RRSIGRecordContent &rrc, bool ksk); 
    4545 
  • trunk/pdns/pdns/dnsseckeeper.hh

    r1785 r1790  
    6868 
    6969  void create(unsigned int bits); 
    70   std::string convertToISC(unsigned int algorithm); 
     70  std::string convertToISC(unsigned int algorithm) const; 
    7171 
    7272private: 
     
    102102    
    103103public: 
    104   explicit DNSSECKeeper(const std::string& dirname) : d_dirname(dirname){} 
    105  
    106104  bool haveActiveKSKFor(const std::string& zone, DNSSECPrivateKey* ksk=0); 
    107105   
     
    109107  DNSSECPrivateKey getKeyById(const std::string& zone, unsigned int id); 
    110108  void addKey(const std::string& zname, bool keyOrZone, int algorithm=5, int bits=0, bool active=true); 
     109  void addKey(const std::string& zname, bool keyOrZone, const DNSSECPrivateKey& dpk, bool active=true); 
    111110  void removeKey(const std::string& zname, unsigned int id); 
    112111  void activateKey(const std::string& zname, unsigned int id); 
     
    118117  void setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& n3p); 
    119118  void unsetNSEC3PARAM(const std::string& zname); 
    120    
    121 private: 
    122   std::string d_dirname; 
    123119}; 
    124120 
  • trunk/pdns/pdns/packethandler.cc

    r1775 r1790  
    205205     
    206206  DNSResourceRecord rr; 
    207   DNSSECKeeper dk(::arg()["key-repository"]); 
    208  
     207  DNSSECKeeper dk; 
    209208 
    210209  bool haveOne=false; 
     
    244243 
    245244  DNSResourceRecord rr; 
    246   DNSSECKeeper dk(::arg()["key-repository"]); 
     245  DNSSECKeeper dk; 
    247246 
    248247  NSEC3PARAMRecordContent ns3prc; 
     
    535534void PacketHandler::addNSECX(DNSPacket *p, DNSPacket *r, const string& target, const string& auth, int mode) 
    536535{ 
    537   DNSSECKeeper dk(::arg()["key-repository"]); 
     536  DNSSECKeeper dk; 
    538537  NSEC3PARAMRecordContent ns3rc; 
    539538  cerr<<"Doing NSEC3PARAM lookup for '"<<auth<<"': "; 
     
    950949    RRSIGRecordContent rrc; 
    951950    for(int ksk =0 ; ksk < 2; ++ksk) { 
    952       getRRSIGForRRSET(::arg()["key-repository"], p->qdomain, iter.first, 3600, iter.second, rrc, ksk); 
     951      getRRSIGForRRSET(p->qdomain, iter.first, 3600, iter.second, rrc, ksk); 
    953952      rr.content=rrc.getZoneRepresentation(); 
    954953      r->addRecord(rr); 
  • trunk/pdns/pdns/tcpreceiver.cc

    r1763 r1790  
    462462  // this is where the DNSKEYs go 
    463463   
    464   DNSSECKeeper dk(::arg()["key-repository"]); 
     464  DNSSECKeeper dk; 
    465465  DNSSECKeeper::keyset_t keys = dk.getKeys(target); 
    466466  BOOST_FOREACH(const DNSSECKeeper::keyset_t::value_type& value, keys) {