add Validator

Change-Id: Ib8ce9023aad0782f934e8e6e559840b559d68208
diff --git a/src/validator.cpp b/src/validator.cpp
new file mode 100644
index 0000000..721b311
--- /dev/null
+++ b/src/validator.cpp
@@ -0,0 +1,125 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS 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
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "logger.hpp"
+#include "config.hpp"
+#include "validator.hpp"
+
+#include "ndn-cxx/data.hpp"
+#include <ndn-cxx/security/validator-config.hpp>
+
+
+namespace ndn {
+namespace ndns {
+NDNS_LOG_INIT("validator");
+
+std::string Validator::VALIDATOR_CONF_FILE = DEFAULT_CONFIG_PATH "/" "validator.conf";
+
+Validator::Validator(Face& face, const std::string& confFile /* = VALIDATOR_CONF_FILE */)
+  : ValidatorConfig(face)
+{
+  try {
+    this->load(confFile);
+    NDNS_LOG_TRACE("Validator loads configuration: " << confFile);
+  }
+  catch (std::exception&) {
+    std::string config =
+      "rule                                                                       \n"
+      "{                                                                          \n"
+      "  id \"NDNS Validator\"                                                    \n"
+      "  for data                                                                 \n"
+      "  checker                                                                  \n"
+      "  {                                                                        \n"
+      "    type customized                                                        \n"
+      "    sig-type rsa-sha256                                                    \n"
+      "    key-locator                                                            \n"
+      "    {                                                                      \n"
+      "      type name                                                            \n"
+      "      hyper-relation                                                       \n"
+      "      {                                                                    \n"
+      "        k-regex ^(<>*)<KEY>(<>*)<><ID-CERT>$                               \n"
+      "        k-expand \\\\1\\\\2                                                \n"
+      "        h-relation is-prefix-of                                            \n"
+      "        p-regex ^(<>*)[<KEY><NDNS>](<>*)<><>$                              \n"
+      "        p-expand \\\\1\\\\2                                                \n"
+      "      }                                                                    \n"
+      "    }                                                                      \n"
+      "  }                                                                        \n"
+      "}                                                                          \n"
+      "                                                                           \n"
+      "                                                                           \n"
+      "trust-anchor                                                               \n"
+      "{                                                                          \n"
+      "  type file                                                                \n"
+      "  file-name \""
+      ;
+
+    config += "anchors/root.cert";
+
+    config +=
+      "\"                                                                         \n"
+      "}                                                                          \n"
+      "                                                                           \n"
+      ;
+
+    this->load(config, "embededConf");
+    NDNS_LOG_TRACE("Validator loads embedded configuration with anchors path: anchors/root.cert");
+  }
+
+}
+
+void
+Validator::validate(const Data& data,
+                    const OnDataValidated& onValidated,
+                    const OnDataValidationFailed& onValidationFailed)
+{
+  NDNS_LOG_TRACE("[* ?? *] verify data: " << data.getName() << ". KeyLocator: "
+                 << data.getSignature().getKeyLocator().getName());
+  ValidatorConfig::validate(data,
+                            [this, onValidated](const shared_ptr<const Data>& data)
+                            // onValidated here cannot use reference, since this is non-block
+                            {
+                              onValidated(data);
+                              this->onDataValidated(data);
+                            },
+                            [this, onValidationFailed](const shared_ptr<const Data>& data,
+                                                       const std::string& str)
+                            {
+                              onValidationFailed(data, str);
+                              this->onDataValidationFailed(data, str);
+                            }
+                            );
+}
+
+void
+Validator::onDataValidated(const shared_ptr<const Data>& data)
+{
+  NDNS_LOG_TRACE("[* VV *] pass validation: " << data->getName() << ". KeyLocator = "
+                 << data->getSignature().getKeyLocator().getName());
+}
+
+void
+Validator::onDataValidationFailed(const shared_ptr<const Data>& data, const std::string& str)
+{
+  NDNS_LOG_WARN("[* XX *] fail validation: " << data->getName() << ". due to: " << str
+                << ". KeyLocator = " << data->getSignature().getKeyLocator().getName());
+}
+
+} // namespace ndns
+} // namespace ndn
diff --git a/src/validator.hpp b/src/validator.hpp
new file mode 100644
index 0000000..dc7f656
--- /dev/null
+++ b/src/validator.hpp
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California.
+ *
+ * This file is part of NDNS (Named Data Networking Domain Name Service).
+ * See AUTHORS.md for complete list of NDNS authors and contributors.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS 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
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDNS_VALIDATOR_HPP
+#define NDNS_VALIDATOR_HPP
+
+#include "config.hpp"
+
+#include "ndn-cxx/data.hpp"
+#include <ndn-cxx/security/validator-config.hpp>
+
+
+namespace ndn {
+namespace ndns {
+
+/**
+ * @brief NDNS validator, which validates Data with hierarchical way. Validator is used in three
+ * scenarios:
+ * 1) Dig client gets the final response Data;
+ * 2) Authoritative name server receives update request;
+ * 3) Update client gets the result of update request.
+ *
+ * @note Compared to its parent class, ValidatorConfig, the class provides is customized according
+ * to config file and the above working scenarios:
+ * 1) give the default path of config file;
+ * 2) default rule is the given path if not valid or the content is wrong.
+ *    Validator rule is must for NDNS, the daemon/dig/update must work even without manually edit
+ * 3) some wrapper provides default behavior when verification succeeds or fails
+ */
+class Validator : public ValidatorConfig
+{
+
+public:
+  static std::string VALIDATOR_CONF_FILE;
+
+  /**
+   * @brief the callback function which is called after validation finishes
+   * @param[in] callback The function is called after validation finishes, no matter validation
+   * succeeds or fails
+   */
+  explicit
+  Validator(Face& face, const std::string& confFile = VALIDATOR_CONF_FILE);
+
+  /**
+   * @brief validate the Data
+   */
+  virtual void
+  validate(const Data& data,
+           const OnDataValidated& onValidated,
+           const OnDataValidationFailed& onValidationFailed);
+
+private:
+  /**
+   * @brief the default callback function on data validated
+   */
+  void
+  onDataValidated(const shared_ptr<const Data>& data);
+
+  /**
+   * @brief the default callback function on data validation failed
+   */
+  void
+  onDataValidationFailed(const shared_ptr<const Data>& data, const std::string& str);
+
+};
+
+
+} // namespace ndns
+} // namespace ndn
+
+#endif // NDNS_VALIDATOR_HPP