]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add tsigutils.{hh,cc}
authorPieter Lexis <pieter.lexis@powerdns.com>
Tue, 21 Aug 2018 13:38:45 +0000 (15:38 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Tue, 21 Aug 2018 16:40:53 +0000 (18:40 +0200)
 * Adds a `makeTSIGKey` function
 * Uses memcpy to avoid aliasing

pdns/Makefile.am
pdns/pdnsutil.cc
pdns/tsigutils.cc [new file with mode: 0644]
pdns/tsigutils.hh [new file with mode: 0644]
pdns/ws-auth.cc

index dca59982a8e27ffa1b61df4f57081377efd7ad06..8cdfb40f769cd98bdf94e4c37d733adcba656f5c 100644 (file)
@@ -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
index c275f71b9006c8019ee2811b080bc543f7742b4e..e41159c0c5e7021c9b05db331cc1bd386f228358 100644 (file)
@@ -11,6 +11,7 @@
 #include <boost/program_options.hpp>
 #include <boost/assign/std/vector.hpp>
 #include <boost/assign/list_of.hpp>
+#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 (file)
index 0000000..5559265
--- /dev/null
@@ -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 <string>
+
+/*
+ * 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 (file)
index 0000000..bffd097
--- /dev/null
@@ -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 <string>
+
+std::string makeTSIGKey(const DNSName& algorithm);
index 741a88860885d0f5f302dcfd522a9338c75242ce..c274312763d4d2ea1748676ed869e951207e06b4 100644 (file)
@@ -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