]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[sedhcpv6] still real sign/verify to do (checkpoint)
authorFrancis Dupont <fdupont@isc.org>
Sun, 31 May 2015 12:02:19 +0000 (14:02 +0200)
committerFrancis Dupont <fdupont@isc.org>
Sun, 31 May 2015 12:02:19 +0000 (14:02 +0200)
13 files changed:
src/bin/dhcp6/Makefile.am
src/bin/dhcp6/dhcp6_log.h
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/kea-dhcp6.xml
src/bin/dhcp6/sedhcp6_messages.mes [new file with mode: 0644]
src/lib/dhcp/dhcp6.h
src/lib/dhcp/libdhcp++.cc
src/lib/dhcp/pkt6.cc
src/lib/dhcp/pkt_filter_inet.cc
src/lib/dhcp/tests/libdhcp++_unittest.cc
src/lib/dhcpsrv/host.h
src/lib/util/ntp_utils.cc

index cc9e9a863a3ce8a00ab67d1d40dd3b6f5265277b..19aa4cd2b67a980be5f50371375747cd59c62f8d 100644 (file)
@@ -21,7 +21,8 @@ if USE_STATIC_LINK
 AM_LDFLAGS = -static
 endif
 
-CLEANFILES = spec_config.h dhcp6_messages.h dhcp6_messages.cc s-messages
+CLEANFILES = spec_config.h dhcp6_messages.h dhcp6_messages.cc \
+       sedhcp6_messages.h sedhcp6_messages.cc s-messages
 
 man_MANS = kea-dhcp6.8
 DISTCLEANFILES = $(man_MANS)
@@ -46,13 +47,15 @@ endif
 spec_config.h: spec_config.h.pre
        $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
 
-dhcp6_messages.h dhcp6_messages.cc: s-messages
+dhcp6_messages.h dhcp6_messages.cc sedhcp6_messages.h sedhcp6_messages.cc: s-messages
 
-s-messages: dhcp6_messages.mes
+s-messages: dhcp6_messages.mes sedhcp6_messages.mes
        $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/bin/dhcp6/dhcp6_messages.mes
+       $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/bin/dhcp6/sedhcp6_messages.mes
        touch $@
 
-BUILT_SOURCES = spec_config.h dhcp6_messages.h dhcp6_messages.cc
+BUILT_SOURCES = spec_config.h dhcp6_messages.h dhcp6_messages.cc \
+       sedhcp6_messages.h sedhcp6_messages.cc
 
 # convenience archive
 
@@ -72,8 +75,9 @@ if CONFIG_BACKEND_JSON
 libdhcp6_la_SOURCES += kea_controller.cc
 endif
 
-nodist_libdhcp6_la_SOURCES = dhcp6_messages.h dhcp6_messages.cc
-EXTRA_DIST += dhcp6_messages.mes
+nodist_libdhcp6_la_SOURCES  = dhcp6_messages.h dhcp6_messages.cc
+nodist_libdhcp6_la_SOURCES += sedhcp6_messages.h sedhcp6_messages.cc
+EXTRA_DIST += dhcp6_messages.mes sedhcp6_messages.mes
 
 sbin_PROGRAMS = kea-dhcp6
 
index 422af9c198394a662ea860a56dd971fb9ce2c5cd..cc3f9cdb945efdbe1ab554cffe6d3f5edea021f3 100644 (file)
@@ -16,6 +16,7 @@
 #define DHCP6_LOG_H
 
 #include <dhcp6/dhcp6_messages.h>
+#include <dhcp6/sedhcp6_messages.h>
 #include <log/logger_support.h>
 #include <log/macros.h>
 
index a91a88a4412f5eabd5c46351a05da1af81c7d869..54191c2d4fb558a5a34db68fddcc4e26913d8f75 100644 (file)
@@ -2887,6 +2887,8 @@ bool Dhcpv6Srv::validateSeDhcpOptions(const Pkt6Ptr& query, Pkt6Ptr& answer,
         bool has_pubkey = false;
         if (query->getOption(D6O_PUBLIC_KEY)) {
             has_pubkey = true;
+           LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, SEDHCP6_OPTION_RECEIVED)
+               .arg("public key");
             if (query->getOptions(D6O_PUBLIC_KEY).size() > 1) {
                 answer->addOption(createStatusCode(STATUS_UnspecFail,
                             "More than one public key option"));
@@ -2897,6 +2899,8 @@ bool Dhcpv6Srv::validateSeDhcpOptions(const Pkt6Ptr& query, Pkt6Ptr& answer,
         bool has_cert = false;
         if (query->getOption(D6O_CERTIFICATE)) {
             has_cert = true;
+           LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, SEDHCP6_OPTION_RECEIVED)
+               .arg("certificate");
             if (query->getOptions(D6O_CERTIFICATE).size() > 1) {
                 answer->addOption(createStatusCode(STATUS_UnspecFail,
                             "More than one certificate option"));
@@ -2929,6 +2933,7 @@ bool Dhcpv6Srv::validateSeDhcpOptions(const Pkt6Ptr& query, Pkt6Ptr& answer,
         }
         // Unsecure
         if (!signopt_required && !signopt) {
+           LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, SEDHCP6_UNSECURE);
             return (true);
         }
         // signopt is true
@@ -3027,6 +3032,8 @@ bool Dhcpv6Srv::validateSeDhcpOptions(const Pkt6Ptr& query, Pkt6Ptr& answer,
             tmstmp_opt = query->getOption(D6O_TIMESTAMP);
         }
         if (tmstmp_opt) {
+           LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, SEDHCP6_OPTION_RECEIVED)
+               .arg("timestamp");
             // Get timestamps in NTP format
             vector<uint8_t> tmstmp_bin = tmstmp_opt->getData();
             if (!ts_new.from_binary(tmstmp_bin)) {
@@ -3066,9 +3073,11 @@ bool Dhcpv6Srv::validateSeDhcpOptions(const Pkt6Ptr& query, Pkt6Ptr& answer,
 
         // Update timestamps
         if (update_tmstmp) {
-            // TODO (ctx.host_ is a const)
-            // ctx.host_->setRDlast(rd_new);
-            // ctx.host_->setTSlast(ts_new);
+           Host* hp = const_cast<Host*>(ctx.host_.get());
+            hp->setRDlast(rd_new);
+            hp->setTSlast(ts_new);
+           LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL,
+                     SEDHCP6_TIMESTAMP_UPDATED);
         }
     }
 
@@ -3090,12 +3099,17 @@ void Dhcpv6Srv::appendSeDhcpOptions(Pkt6Ptr& answer) {
     if (state->getSignAnswers() && key && cred) {
         // Add the credential (public key or certificate) option
         uint16_t cred_type = D6O_PUBLIC_KEY;
+       string opt_name = "public key";
         if (cred->getAsymKeyKind() == CERT) {
             cred_type = D6O_CERTIFICATE;
+           opt_name = "certificate";
         }
         OptionBuffer buf = cred->exportkey(cred->getAsymKeyKind(), ASN1);
         OptionPtr cred_opt(new Option(Option::V6, cred_type, buf));
         answer->addOption(cred_opt);
+       LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, SEDHCP6_OPTION_ADDED)
+           .arg(opt_name)
+           .arg(cred_opt->len());
 
         // Add the signature option
         uint8_t ha_id = SHA_256;
@@ -3112,6 +3126,9 @@ void Dhcpv6Srv::appendSeDhcpOptions(Pkt6Ptr& answer) {
         assert(sig_def);
         OptionCustomPtr sig_opt(new OptionCustom(*sig_def, Option::V6, sig));
         answer->addOption(sig_opt);
+       LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, SEDHCP6_OPTION_ADDED)
+           .arg("signature")
+           .arg(sig_opt->len());
     }
 
     // Add timestamps
@@ -3122,6 +3139,9 @@ void Dhcpv6Srv::appendSeDhcpOptions(Pkt6Ptr& answer) {
         const OptionBuffer buf = val.to_binary();
         OptionPtr tmsmtp_opt(new Option(Option::V6, D6O_TIMESTAMP, buf));
         answer->addOption(tmsmtp_opt);
+       LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, SEDHCP6_OPTION_ADDED)
+           .arg("timestamp")
+           .arg(tmsmtp_opt->len());
     }
 }
 
@@ -3130,17 +3150,25 @@ void Dhcpv6Srv::finalizeSignature(Pkt6Ptr& tbs) {
     ConstCfgSeDhcp6Ptr state =
         CfgMgr::instance().getCurrentCfg()->getCfgSeDhcp6();
     if (!state) {
-        isc_throw(Unexpected, "no secure DHCPv6 configuration state");
+       LOG_ERROR(dhcp6_logger, SEDHCP6_SIGNATURE_FINALIZE_FAIL)
+           .arg("no secure DHCPv6 configuration state");
+       return;
     }
     if (!state->getSignAnswers()) {
-        isc_throw(Unexpected, "Signing answers is disabled");
+       LOG_ERROR(dhcp6_logger, SEDHCP6_SIGNATURE_FINALIZE_FAIL)
+           .arg("Signing answers is disabled");
+       return;
     }
     CfgSeDhcp6::AsymPtr key = state->getPrivateKey();
     if (!key) {
-        isc_throw(Unexpected, "No private key configured");
+       LOG_ERROR(dhcp6_logger, SEDHCP6_SIGNATURE_FINALIZE_FAIL)
+           .arg("No private key configured");
+       return;
     }
     if (!tbs->getSignatureOffset()) {
-        isc_throw(Unexpected, "null signature offset");
+       LOG_ERROR(dhcp6_logger, SEDHCP6_SIGNATURE_FINALIZE_FAIL)
+           .arg("null signature offset");
+       return;
     }
     // TODO
 }
index f56cfff208b41bca35f910e2dd1e44ea767fb276..37b32f097901a02511de5ae4bf3e5c7565e00e0b 100644 (file)
@@ -686,7 +686,7 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id,
     } else if (config_id.compare("relay-supplied-options") == 0) {
         parser = new RSOOListConfigParser(config_id);
     } else if (config_id.compare("secure-dhcp6") == 0) {
-       parser = new SeDhcp6Parser(config_id, Option::V6);
+        parser = new SeDhcp6Parser(config_id, Option::V6);
     } else {
         isc_throw(DhcpConfigError,
                 "unsupported global configuration parameter: "
index 3b504275417d77472288ea1c11284d3d91d5cb63..dafd31e4df823a6661d86c627f4ee30abc440f6b 100644 (file)
@@ -1,6 +1,6 @@
 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
                "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
-              [<!ENTITY mdash "&#8212;">]>
+               [<!ENTITY mdash "&#8212;">]>
 <!--
  - Copyright (C) 2011, 2014 Internet Systems Consortium, Inc. ("ISC")
  -
diff --git a/src/bin/dhcp6/sedhcp6_messages.mes b/src/bin/dhcp6/sedhcp6_messages.mes
new file mode 100644 (file)
index 0000000..c98ccae
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+$NAMESPACE isc::dhcp
+
+% SEDHCP6_OPTION_ADDED secure DHCPv6 option has been added: type %1, size %2
+This debug message is printed when a secure DHCPv6 option is added
+to an answer packet.
+
+% SEDHCP6_OPTION_RECEIVED secure DHCPv6 option has been received: type %1
+This debug message is printed when a secure DHCPv6 option is found
+during incoming packet validation.
+
+% SEDHCP6_SIGNATURE_FINALIZE_FAIL signature finalize error: %1
+This error message indicates that the signature finalize has failed.
+This is a "should not happen" condition which reflects an internal
+error.
+
+% SEDHCP6_TIMESTAMP_UPDATED timestamps have been updated
+This debug message is printed when the host timestamps have been updated.
+
+% SEDHCP6_UNSECURE incoming packet is unsecure
+This debug message is printed when the secure DHCPv6 validation
+concludes the incoming packet is unsecure.
+
index 9ef2caa8d0fe72863ca16429c0b215dc2150dcdf..1f3ef2fc36d02f06d7754469f989fd2c780c279f 100644 (file)
@@ -125,6 +125,7 @@ extern const int dhcpv6_type_name_max;
 #define HWTYPE_INFINIBAND  0x0020
 
 // Secure DHCPv6 (draft-ietf-dhc-sedhcpv6-07.txt)
+// (can't use an enum because HashAlgorithm name is already taken)
 #define SHA_256                 1
 #define SHA_512                 2
 #define RSASSA_PKCS1v1_5        1
index 1bf7c163629d88af23b8d95cfeb995aeb2f37bf7..8297f787cb0706c434d610cafdb23e709e8aa312 100644 (file)
@@ -247,7 +247,7 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
                                isc::dhcp::OptionCollection& options,
                                size_t* relay_msg_offset /* = 0 */,
                                size_t* relay_msg_len /* = 0 */,
-                              size_t* signature_offset /* = 0 */) {
+                               size_t* signature_offset /* = 0 */) {
     size_t offset = 0;
     size_t length = buf.size();
 
@@ -293,10 +293,10 @@ size_t LibDHCP::unpackOptions6(const OptionBuffer& buf,
             continue;
         }
 
-       if (opt_type == D6O_SIGNATURE && signature_offset) {
-           // remember offset of the beginning of the (last) signature option
-           *signature_offset = offset;
-       }
+        if (opt_type == D6O_SIGNATURE && signature_offset) {
+            // remember offset of the beginning of the (last) signature option
+            *signature_offset = offset;
+        }
 
         if (opt_type == D6O_VENDOR_OPTS) {
             if (offset + 4 > length) {
index 7b1635ebc38007909ac969bd33d7a78e5d7dab8a..13ad242f50571bcf888431c90526275738946d52 100644 (file)
@@ -248,7 +248,7 @@ Pkt6::packUDP() {
         for (OptionCollection::const_iterator it = options_.begin();
              it != options_.end(); ++it) {
             // Remember where the certificate is inserted
-            if (it->first == D6O_CERTIFICATE) {
+            if (it->first == D6O_SIGNATURE) {
                 signature_offset_ = buffer_out_.getLength();
             }
             it->second->pack(buffer_out_);
index 468d0335eac268019b20a2d92e30e811271a34e4..b49991111621dcd4f4a294e928b3d086f4420072 100644 (file)
@@ -237,7 +237,7 @@ PktFilterInet::send(const Iface&, uint16_t sockfd,
     struct in_pktinfo* pktinfo =(struct in_pktinfo *)CMSG_DATA(cmsg);
     memset(pktinfo, 0, sizeof(struct in_pktinfo));
     pktinfo->ipi_ifindex = pkt->getIndex();
-       pktinfo->ipi_spec_dst.s_addr = htonl(pkt->getLocalAddr()); // set the source IP address
+        pktinfo->ipi_spec_dst.s_addr = htonl(pkt->getLocalAddr()); // set the source IP address
     m.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
 #endif
 
index 4b482fb76f854f13a952f29f8c99ba09f13b9cbf..1d7a2aa202f560dec5a56f4da3c13a9ec142e322 100644 (file)
@@ -1159,7 +1159,7 @@ TEST_F(LibDhcpTest, stdOptionDefs6) {
                                     typeid(OptionCustom));
 
     LibDhcpTest::testStdOptionDefs6(D6O_TIMESTAMP, begin, begin + 8,
-                                    typeid(OptionCustom));
+                                    typeid(Option));
 }
 
 // This test checks if the DHCPv6 option definition can be searched by
index 9341228e50ecae0887b1d2b5ff34aaab83ca7717..6e69107a2b27c0be3b42c94b9ead580a8d3cee19 100644 (file)
@@ -437,24 +437,24 @@ public:
     ///
     /// @param timestamp Date in NTP format
     void setRDlast(const isc::util::Ntp& timestamp) {
-       rd_last_ = timestamp;
+        rd_last_ = timestamp;
     }
 
     /// @brief Returns RDlast
     const isc::util::Ntp& getRDlast() const {
-       return (rd_last_);
+        return (rd_last_);
     }
 
     /// @brief Sets the date of the last received and accepted timestamp
     ///
     /// @param timestamp Date in NTP format
     void setTSlast(const isc::util::Ntp& timestamp) {
-       ts_last_ = timestamp;
+        ts_last_ = timestamp;
     }
 
     /// @brief Returns TSlast
     const isc::util::Ntp& getTSlast() const {
-       return (ts_last_);
+        return (ts_last_);
     }
 
     /// @brief Returns information about the host in the textual format.
index 17434b0e5b3f3a3f0f2b777b313769df27ae3d11..912ba8af8408a7008ff729cccc04f1b193662a04 100644 (file)
@@ -52,7 +52,7 @@ Ntp::Ntp(uint64_t sec, uint16_t fraction)
 Ntp::Ntp(const struct timeval* tv)
 {
     ntp_sec_ = static_cast<uint32_t>(tv->tv_sec) + EPOCH_ADJUST;
-    uint32_t fcvt = (tv->tv_usec * 65536U) / 1000000UL;
+    uint64_t fcvt = (static_cast<uint64_t>(tv->tv_usec) * 65536U) / 1000000UL;
     ntp_fraction_ = static_cast<uint16_t>(fcvt & 0xffff);
 }