From: Pieter Lexis Date: Tue, 21 Aug 2018 13:38:45 +0000 (+0200) Subject: Add tsigutils.{hh,cc} X-Git-Tag: auth-4.2.0-alpha1~17^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac5298aaab1ea003f18954561e4852eff93468bc;p=thirdparty%2Fpdns.git Add tsigutils.{hh,cc} * Adds a `makeTSIGKey` function * Uses memcpy to avoid aliasing --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index dca59982a8..8cdfb40f76 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -224,6 +224,7 @@ pdns_server_SOURCES = \ stubresolver.cc stubresolver.hh \ tcpreceiver.cc tcpreceiver.hh \ tsigverifier.cc tsigverifier.hh \ + tsigutils.hh tsigutils.cc \ tkey.cc \ ueberbackend.cc ueberbackend.hh \ unix_semaphore.cc \ @@ -337,6 +338,7 @@ pdnsutil_SOURCES = \ sstuff.hh \ statbag.cc \ stubresolver.cc stubresolver.hh \ + tsigutils.hh tsigutils.cc \ ueberbackend.cc \ unix_utility.cc \ zoneparser-tng.cc diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index c275f71b90..e41159c0c5 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -11,6 +11,7 @@ #include #include #include +#include "tsigutils.hh" #include "dnsbackend.hh" #include "ueberbackend.hh" #include "arguments.hh" @@ -2779,35 +2780,15 @@ try return 0; } DNSName name(cmds[1]); - string algo = cmds[2]; + DNSName algo(cmds[2]); string key; - char tmpkey[64]; - - size_t klen = 0; - if (algo == "hmac-md5") { - klen = 32; - } else if (algo == "hmac-sha1") { - klen = 32; - } else if (algo == "hmac-sha224") { - klen = 32; - } else if (algo == "hmac-sha256") { - klen = 64; - } else if (algo == "hmac-sha384") { - klen = 64; - } else if (algo == "hmac-sha512") { - klen = 64; - } else { - cerr << "Cannot generate key for " << algo << endl; - cerr << usage << endl; + try { + key = makeTSIGKey(algo); + } catch(const PDNSException& e) { + cerr << "Could not create new TSIG key " << name << " " << algo << ": "<< e.reason << endl; return 1; } - cerr << "Generating new key with " << klen << " bytes" << endl; - for(size_t i = 0; i < klen; i+=4) { - *(unsigned int*)(tmpkey+i) = dns_random(0xffffffff); - } - key = Base64Encode(std::string(tmpkey, klen)); - UeberBackend B("default"); if (B.setTSIGKey(name, DNSName(algo), key)) { // you are feeling bored, put up DNSName(algo) up earlier cout << "Create new TSIG key " << name << " " << algo << " " << key << endl; diff --git a/pdns/tsigutils.cc b/pdns/tsigutils.cc new file mode 100644 index 0000000000..5559265486 --- /dev/null +++ b/pdns/tsigutils.cc @@ -0,0 +1,54 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "dnsname.hh" +#include "base64.hh" +#include "dns_random.hh" +#include "misc.hh" +#include "pdnsexception.hh" +#include + +/* + * Returns a generated Base64'd TSIG key + * + * Will raise a PDNSException() if algorithm is invalid + */ +std::string makeTSIGKey(const DNSName& algorithm) { + TSIGHashEnum tsigHashEnum; + if (!getTSIGHashEnum(algorithm, tsigHashEnum)) { + throw PDNSException("Invalid TSIG algorithm: " + algorithm.toStringNoDot()); + } + + size_t klen = 64; + if (tsigHashEnum == TSIG_MD5 + || tsigHashEnum == TSIG_SHA1 + || tsigHashEnum == TSIG_SHA224) { + klen = 32; + } + + char tmpkey[64]; + for (size_t i = 0; i < klen; i += 4) { + unsigned int t = dns_random(0xffffffff); + memcpy(tmpkey + i, &t, 4); + } + return Base64Encode(std::string(tmpkey, klen)); +} diff --git a/pdns/tsigutils.hh b/pdns/tsigutils.hh new file mode 100644 index 0000000000..bffd0971d7 --- /dev/null +++ b/pdns/tsigutils.hh @@ -0,0 +1,26 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "dnsname.hh" +#include + +std::string makeTSIGKey(const DNSName& algorithm); diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 741a888608..c274312763 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -45,6 +45,7 @@ #include "zoneparser-tng.hh" #include "common_startup.hh" #include "auth-caches.hh" +#include "tsigutils.hh" using json11::Json; @@ -1352,17 +1353,11 @@ static void apiServerTSIGKeys(HttpRequest* req, HttpResponse* resp) { string content = document["key"].string_value(); if (content.empty()) { - size_t klen = 64; - if (algo.toStringNoDot() == "hmac-md5" - || algo.toStringNoDot() == "hmac-sha1" - || algo.toStringNoDot() == "hmac-sha224") { - klen = 32; - } - char tmpkey[64]; - for(size_t i = 0; i < klen; i+=4) { - *(unsigned int*)(tmpkey+i) = dns_random(0xffffffff); + try { + content = makeTSIGKey(algo); + } catch (const PDNSException& e) { + throw HttpBadRequestException(e.reason); } - content = Base64Encode(std::string(tmpkey, klen)); } // Will throw an ApiException or HttpConflictException on error