| 1 | #include "dnsseckeeper.hh" |
|---|
| 2 | #include "dnssecinfra.hh" |
|---|
| 3 | #include "statbag.hh" |
|---|
| 4 | #include <boost/foreach.hpp> |
|---|
| 5 | #include <boost/program_options.hpp> |
|---|
| 6 | |
|---|
| 7 | using namespace boost; |
|---|
| 8 | namespace po = boost::program_options; |
|---|
| 9 | po::variables_map g_vm; |
|---|
| 10 | |
|---|
| 11 | StatBag S; |
|---|
| 12 | |
|---|
| 13 | string humanTime(time_t t) |
|---|
| 14 | { |
|---|
| 15 | char ret[256]; |
|---|
| 16 | struct tm tm; |
|---|
| 17 | localtime_r(&t, &tm); |
|---|
| 18 | strftime(ret, sizeof(ret)-1, "%c", &tm); // %h:%M %Y-%m-%d |
|---|
| 19 | return ret; |
|---|
| 20 | } |
|---|
| 21 | |
|---|
| 22 | int main(int argc, char** argv) |
|---|
| 23 | { |
|---|
| 24 | po::options_description desc("Allowed options"); |
|---|
| 25 | desc.add_options() |
|---|
| 26 | ("help,h", "produce help message") |
|---|
| 27 | ("key-repository,k", po::value<string>()->default_value("./keys"), "Location of keys") |
|---|
| 28 | ("verbose,v", po::value<bool>(), "be verbose") |
|---|
| 29 | ("force", "force an action") |
|---|
| 30 | ("commands", po::value<vector<string> >()); |
|---|
| 31 | |
|---|
| 32 | po::positional_options_description p; |
|---|
| 33 | p.add("commands", -1); |
|---|
| 34 | po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), g_vm); |
|---|
| 35 | po::notify(g_vm); |
|---|
| 36 | |
|---|
| 37 | vector<string> cmds; |
|---|
| 38 | |
|---|
| 39 | if(g_vm.count("commands")) |
|---|
| 40 | cmds = g_vm["commands"].as<vector<string> >(); |
|---|
| 41 | |
|---|
| 42 | if(cmds.empty() || g_vm.count("help")) { |
|---|
| 43 | cerr<<"Usage: \npdnssec [options] [show-zone] [sign-zone] [update-zone-keys]\n"; |
|---|
| 44 | cerr<<desc<<endl; |
|---|
| 45 | return 0; |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | DNSSECKeeper dk(g_vm["key-repository"].as<string>()); |
|---|
| 49 | |
|---|
| 50 | if(cmds[0] == "update-zone-keys") { |
|---|
| 51 | if(cmds.size() != 2) { |
|---|
| 52 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; |
|---|
| 53 | return 0; |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | const string& zone=cmds[1]; |
|---|
| 57 | DNSSECPrivateKey dpk; |
|---|
| 58 | |
|---|
| 59 | if(!dk.haveKSKFor(zone, &dpk)) { |
|---|
| 60 | cerr << "No KSK for zone '"<<zone<<"', can't update the ZSKs"<<endl; |
|---|
| 61 | return 0; |
|---|
| 62 | } |
|---|
| 63 | DNSSECKeeper::zskset_t zskset=dk.getZSKsFor(zone); |
|---|
| 64 | |
|---|
| 65 | int inforce=0; |
|---|
| 66 | if(!zskset.empty()) { |
|---|
| 67 | cerr<<"There were ZSKs already for zone '"<<zone<<"': "<<endl; |
|---|
| 68 | |
|---|
| 69 | BOOST_FOREACH(DNSSECKeeper::zskset_t::value_type value, zskset) { |
|---|
| 70 | cerr<<"Tag = "<<value.first.getDNSKEY().getTag()<<"\tActive: "<<value.second<<", "<<value.first.beginValidity<<" - "<<value.first.endValidity<<endl; |
|---|
| 71 | if(value.second) |
|---|
| 72 | inforce++; |
|---|
| 73 | } |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | if(inforce == 2) { |
|---|
| 77 | cerr << "Two ZSKs were active already, not generating a third" << endl; |
|---|
| 78 | return 0; |
|---|
| 79 | } |
|---|
| 80 | dk.addZSKFor(zone); |
|---|
| 81 | dk.addZSKFor(zone, true); // 'next' |
|---|
| 82 | |
|---|
| 83 | zskset = dk.getZSKsFor(zone); |
|---|
| 84 | if(zskset.empty()) { |
|---|
| 85 | cerr<<"This should not happen, still no ZSK!"<<endl; |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | cerr<<"There are now "<<zskset.size()<<" ZSKs"<<endl; |
|---|
| 89 | BOOST_FOREACH(DNSSECKeeper::zskset_t::value_type value, zskset) { |
|---|
| 90 | cerr<<"Tag = "<<value.first.getDNSKEY().getTag()<<"\tActive: "<<value.second<<endl; |
|---|
| 91 | } |
|---|
| 92 | |
|---|
| 93 | } |
|---|
| 94 | else if(cmds[0] == "show-zone") { |
|---|
| 95 | if(cmds.size() != 2) { |
|---|
| 96 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; |
|---|
| 97 | return 0; |
|---|
| 98 | } |
|---|
| 99 | const string& zone=cmds[1]; |
|---|
| 100 | DNSSECPrivateKey dpk; |
|---|
| 101 | |
|---|
| 102 | if(!dk.haveKSKFor(zone, &dpk)) { |
|---|
| 103 | cerr << "No KSK for zone '"<<zone<<"'."<<endl; |
|---|
| 104 | } |
|---|
| 105 | else { |
|---|
| 106 | cerr<<"KSK present:"<<endl; |
|---|
| 107 | cerr<<"Tag = "<<dpk.getDNSKEY().getTag()<<endl; |
|---|
| 108 | cerr<<"KSK DNSKEY = "<<zone<<" IN DNSKEY "<< dpk.getDNSKEY().getZoneRepresentation() << endl; |
|---|
| 109 | cerr<<"DS = "<<zone<<" IN DS "<<makeDSFromDNSKey(zone, dpk.getDNSKEY()).getZoneRepresentation() << endl << endl; |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | |
|---|
| 113 | DNSSECKeeper::zskset_t zskset=dk.getZSKsFor(zone); |
|---|
| 114 | |
|---|
| 115 | int inforce=0; |
|---|
| 116 | if(zskset.empty()) { |
|---|
| 117 | cerr << "No ZSKs for zone '"<<zone<<"'."<<endl; |
|---|
| 118 | } |
|---|
| 119 | else { |
|---|
| 120 | cerr << "ZSKs for zone '"<<zone<<"':"<<endl; |
|---|
| 121 | BOOST_FOREACH(DNSSECKeeper::zskset_t::value_type value, zskset) { |
|---|
| 122 | cerr<<"Tag = "<<value.first.getDNSKEY().getTag()<<"\tActive: "<<value.second<<", "<< humanTime(value.first.beginValidity)<<" - "<<humanTime(value.first.endValidity)<<endl; |
|---|
| 123 | if(value.second) |
|---|
| 124 | inforce++; |
|---|
| 125 | } |
|---|
| 126 | } |
|---|
| 127 | } |
|---|
| 128 | else if(cmds[0] == "sign-zone") { |
|---|
| 129 | if(cmds.size() != 2) { |
|---|
| 130 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; |
|---|
| 131 | return 0; |
|---|
| 132 | } |
|---|
| 133 | const string& zone=cmds[1]; |
|---|
| 134 | DNSSECPrivateKey dpk; |
|---|
| 135 | |
|---|
| 136 | if(dk.haveKSKFor(zone, &dpk) && !g_vm.count("force")) { |
|---|
| 137 | cerr << "There is a key already for zone '"<<zone<<"', use --force to overwrite"<<endl; |
|---|
| 138 | return 0; |
|---|
| 139 | } |
|---|
| 140 | |
|---|
| 141 | dk.addZone(zone); |
|---|
| 142 | |
|---|
| 143 | if(!dk.haveKSKFor(zone, &dpk)) { |
|---|
| 144 | cerr << "This should not happen, still no key!" << endl; |
|---|
| 145 | } |
|---|
| 146 | cerr<<"Created KSK with tag "<<dpk.getDNSKEY().getTag()<<endl; |
|---|
| 147 | |
|---|
| 148 | DNSSECKeeper::zskset_t zskset=dk.getZSKsFor(zone); |
|---|
| 149 | |
|---|
| 150 | if(!zskset.empty() && !g_vm.count("force")) { |
|---|
| 151 | cerr<<"There were ZSKs already for zone '"<<zone<<"'"<<endl; |
|---|
| 152 | return 0; |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | dk.addZSKFor(zone); |
|---|
| 156 | dk.addZSKFor(zone, true); // 'next' |
|---|
| 157 | |
|---|
| 158 | zskset = dk.getZSKsFor(zone); |
|---|
| 159 | if(zskset.empty()) { |
|---|
| 160 | cerr<<"This should not happen, still no ZSK!"<<endl; |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | cerr<<"There are now "<<zskset.size()<<" ZSKs"<<endl; |
|---|
| 164 | BOOST_FOREACH(DNSSECKeeper::zskset_t::value_type value, zskset) { |
|---|
| 165 | cerr<<"Tag = "<<value.first.getDNSKEY().getTag()<<"\tActive: "<<value.second<<endl; |
|---|
| 166 | } |
|---|
| 167 | } |
|---|
| 168 | else { |
|---|
| 169 | cerr<<"Unknown command '"<<cmds[0]<<"'\n"; |
|---|
| 170 | return 1; |
|---|
| 171 | } |
|---|
| 172 | return 0; |
|---|
| 173 | } |
|---|