diff --git a/ca.conf.sample b/ca.conf.sample index de5be8f..a2ca7e1 100644 --- a/ca.conf.sample +++ b/ca.conf.sample @@ -14,9 +14,15 @@ ], "redirect-to": [ - { - "ca-prefix": "/example/site1", - "certificate": "Bv0CvQcwCAdleGFtcGxlCAVzaXRlMQgDS0VZCAh6af3szF4QZwgEc2VsZggJ/QAAAXT6+NCKFAkYAQIZBAA27oAV/QEmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA43hjZT0HUFFJcqwj8lZnd/vg0NrzqvZ4jhsq1c+nv6J3Huc9Uq5jRZwhFQ8nBWT3CeFScO5FUQfNXDIDncZ4vYPFEnockOFVtvmKQ/ELwReUvjH80d1NPGrIVrD0lMRpv2sFr6NW2p7aw6bCSj3OJq7H/+QHDkAryssMZyHwTbPzMZHyYKmxR68CyCCpvLlgp8tYFT+cCrOc3lz3nROK3VFR+apgwubpvl8nbKD10QLcgMHSkLoLEy/Ksq8OH7MQhUEZDjLk/zL9baZ7MiKXtdUZCNTZk13y5z+4aT4TqumLB+obiDXmv6JAi+CkYIMf2ck2IvMV6JgxxIlv3+Ke2wIDAQABFlAbAQEcIQcfCAdleGFtcGxlCAVzaXRlMQgDS0VZCAh6af3szF4QZ/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwNDAwOTMwVDIyNTQwNBf9AQCCSXOqUX40mAIdKCa+nnfJCGZbNowQPJp5kDnyolj5/Ek9x8czyLcX58xTsgYtiPmL5DxMgkRujRJu9INm0pUJIJRlsqhDOwsrxIjlSgwy5AeexYe7SM3rSwljLxTR4MfBw26pym9iYt8ovHXotCDE+etyKwHzXoOgzxORoPXqBGwobNOPnhDfpzHQBFOrPd8qqLAGioNNk/k2U/uyvBbLoZS4ScNVJpfbcvcmzu/A8H/VyT4234LrlISL9WpWlO8J18yzhrXchFR0ZwCoYge5rLZ4vsQhY1WqXHCsYnRa3la6Txz44EWYEBpmk12qnkPt06KAPvQ82N1CICxFb9NY" - } + { + "ca-prefix": "/ndn/edu/ucla", + "certificate": "Bv0BNQcwCANuZG4IA2VkdQgEdWNsYQgDS0VZCAgAdGt6D7S2VAgEc2VsZggJ/QAAAX5lZMOiFAkYAQIZBAA27oAVWzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOKmvwHmK5t+MhMPgft4qmKC7YF9I6UM/o7GFa4BjZQknsqLvxdW2zIAF+iPPHJV0eVAijX6bYrQobuomiWZAY0WUBsBAxwhBx8IA25kbggDZWR1CAR1Y2xhCANLRVkICAB0a3oPtLZU/QD9Jv0A/g8xOTcwMDEwMVQwMDAwMDD9AP8PMjA0MjAxMTJUMDAxNjQ5F0cwRQIgBF/HS0j1DMo/dIILv/6IMUmMAhVtS3m97YgS8tsBhC0CIQCgEm0e6KoBCyV6PiueN9YW9zSSkdg8MLCxsyduP8tRsQ==" + }, + { + "ca-prefix": "/ndn/edu/ucla/cs", + "certificate": "Bv0BPgc0CANuZG4IA2VkdQgEdWNsYQgCY3MIA0tFWQgI27kFrpVyxUAIBHNlbGYICf0AAAF+ZZ/79xQJGAECGQQANu6AFVswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASOLtEWMpMk8tPqPe0VY9SAYA0e969NNy5t0QeseNvr6AbYWQHBR4oa6Ymv3TRlQnyy+IzvKPte5suX/Qhtnjn2FlQbAQMcJQcjCANuZG4IA2VkdQgEdWNsYQgCY3MIA0tFWQgI27kFrpVyxUD9AP0m/QD+DzE5NzAwMTAxVDAwMDAwMP0A/w8yMDQyMDExMlQwMTIxMzAXSDBGAiEAm+aJbcmI0n37Qhear5fo//S02ZlDkmao8a7olSsElx8CIQDD8dZkYfD8xcvYl3vXm7G/NSXFrnrRqxC7NR/4r4swbw==" + "policy-type": "email", + "policy-param": "cs.ucla.edu" + } ] } \ No newline at end of file diff --git a/client.conf.sample b/client.conf.sample index 3a06d7a..53dbd95 100644 --- a/client.conf.sample +++ b/client.conf.sample @@ -2,15 +2,16 @@ "ca-list": [ { - "ca-prefix": "/example", - "ca-info": "An example NDNCERT CA", + "ca-prefix": "/ndncert-demo", + "ca-info": "NDN Testbed NDNCERT CA (Demo)", "max-validity-period": "1296000", - "max-suffix-length": "2", - "probe-parameters": - [ - {"probe-parameter-key": "email"} + "max-suffix-length": "5", + "probe-parameters": [ + { + "probe-parameter-key": "email" + } ], - "certificate": "Bv0CrwcpCAdleGFtcGxlCANLRVkICJev38tR696CCARzZWxmCAn9AAABdPr4U3cUCRgBAhkEADbugBX9ASYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDLjjKYDiimVlQD2vOAOYvu3iCsfS5mzQYOjw1cVS7+EDzC0T841FrmLEtrYe1USBGTSYUKNePspBTDMeAh2WlG+UmnzHyTJEcpv3Dtp/37pYIFlR8vW6TvBkBmCKVR7IDOW0DmBEY2iHbWOCCTyTd9NVyH4XiHqFx+cL9uGRyhVeXcZ5pl335SrnW58Q6tvZeOHS8YXuiAZ8E10Mdhzdmponl2+yRlc1kzkcAX1DQZt7eYXjlSsa5FSphLzw5LNqJuESLcrPRctN+4vs8xTIvWGex8n3+6wAhfXD9DLsO01mJorUxms+mwIKnV7KNLXtwDNsAZYT2BPPnO0H5Zk+tRAgMBAAEWSRsBARwaBxgIB2V4YW1wbGUIA0tFWQgIl6/fy1Hr3oL9AP0m/QD+DzE5NzAwMTAxVDAwMDAwMP0A/w8yMDQwMDkzMFQyMjUzMzIX/QEAZLgyhRsOERTgy5Q2X4FLXQV+r6emud472za0CVT20XHLXofkgybvLvY0UJ80CtuLcNRt/WKTDIKd01SoCnonx1VydKjXsO23RV95pBt/BqZVWakYEJEgbO5KzekpBHbKJmTOWBa/Tmgd9Pd5KFhQm9Ny2ZK1nlyyV37EKqR9jADkDVgRs+Sgr+Z4v14+WePROk7LR11P4NxYfgy2L0CHjpIxiFxnU+CpQL+BoGRQDTFgGq4gxUR45rpt/Y/vl5ImMdmIFDOI5W34AjVIhSLrYH3EDhWgjo9cDqvS+KT45i+t87SBQjtcQbrLl8osQcG+HgRldBv7HEEDVoPL8qL0yg==" + "certificate": "Bv0BLwctCAxuZG5jZXJ0LWRlbW8IA0tFWQgI92c9QI8lJGoIBHNlbGY2CAAAAX7YsardFAkYAQIZBAA27oAVWzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNIu6i4dFU2FwW9641O4XehbwZD3INSgsEehPfZVRnDhQ0l5oRdUGJo6OQhOutExKov7dp+hzmRSAHbiO3dRjdIWThsBAxwfBx0IDG5kbmNlcnQtZGVtbwgDS0VZCAj3Zz1AjyUkav0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwNDIwMjAzVDA5MzcwORdGMEQCIA7CEGlG+KQnJudjqpCzt7IlHRgPV2ni1k5mSu0yZXKtAiAGkqnGwTu1e8LVqZ1XIidt/wDzcYXTQGEoltwhcN6jUw==" } ] } diff --git a/ndncert-send-email-challenge.py b/ndncert-send-email-challenge.py index 61d16ff..20198fc 100755 --- a/ndncert-send-email-challenge.py +++ b/ndncert-send-email-challenge.py @@ -1,12 +1,9 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys import smtplib import argparse import socket -try: # python3 - from configparser import ConfigParser -except ImportError: # python2 - from ConfigParser import SafeConfigParser as ConfigParser +from configparser import ConfigParser from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText diff --git a/src/ca-module.cpp b/src/ca-module.cpp index c2072dd..73582a8 100644 --- a/src/ca-module.cpp +++ b/src/ca-module.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -153,25 +153,40 @@ CaModule::onCaProfileDiscovery(const Interest&) } void -CaModule::onProbe(const Interest& request) -{ +CaModule::onProbe(const Interest& request) { // PROBE Naming Convention: //CA/PROBE/[ParametersSha256DigestComponent] NDN_LOG_TRACE("Received PROBE request"); // process PROBE requests: collect probe parameters - auto parameters = probetlv::decodeApplicationParameters(request.getApplicationParameters()); + std::vector redirectionNames; std::vector availableComponents; - for (auto& item : m_config.nameAssignmentFuncs) { - auto names = item->assignName(parameters); - availableComponents.insert(availableComponents.end(), names.begin(), names.end()); + try { + auto parameters = probetlv::decodeApplicationParameters(request.getApplicationParameters()); + + //collect redirections + for (auto &item : m_config.redirection) { + if (item.second->isRedirecting(parameters)) { + redirectionNames.push_back(item.first->getFullName()); + } + } + + //collect name assignments + for (auto &item : m_config.nameAssignmentFuncs) { + auto names = item->assignName(parameters); + availableComponents.insert(availableComponents.end(), names.begin(), names.end()); + } + } catch (const std::exception& e) { + NDN_LOG_ERROR("[CaModule::onProbe]Error in decoding TLV: " << e.what()); + return; } - if (availableComponents.size() == 0) { + + if (availableComponents.size() == 0 && redirectionNames.size() == 0) { m_face.put(generateErrorDataPacket(request.getName(), ErrorCode::INVALID_PARAMETER, "Cannot generate available names from parameters provided.")); return; } - std::vector availableNames; - for (const auto& component : availableComponents) { + std::vector availableNames; + for (const auto &component : availableComponents) { Name newIdentityName = m_config.caProfile.caPrefix; newIdentityName.append(component); availableNames.push_back(newIdentityName); @@ -180,7 +195,7 @@ CaModule::onProbe(const Interest& request) Data result; result.setName(request.getName()); result.setContent( - probetlv::encodeDataContent(availableNames, m_config.caProfile.maxSuffixLength, m_config.redirection)); + probetlv::encodeDataContent(availableNames, m_config.caProfile.maxSuffixLength, redirectionNames)); result.setFreshnessPeriod(DEFAULT_DATA_FRESHNESS_PERIOD); m_keyChain.sign(result, signingByIdentity(m_config.caProfile.caPrefix)); m_face.put(result); @@ -457,7 +472,7 @@ CaModule::issueCertificate(const RequestState& requestState) Certificate newCert; Name certName = requestState.cert.getKeyName(); - certName.append("NDNCERT").append(ndn::to_string(ndn::random::generateSecureWord64())); + certName.append("NDNCERT").appendVersion(); newCert.setName(certName); newCert.setContent(requestState.cert.getContent()); NDN_LOG_TRACE("cert request content " << requestState.cert); diff --git a/src/challenge/challenge-email.cpp b/src/challenge/challenge-email.cpp index bc624bc..ea0345c 100644 --- a/src/challenge/challenge-email.cpp +++ b/src/challenge/challenge-email.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -29,7 +29,6 @@ NDNCERT_REGISTER_CHALLENGE(ChallengeEmail, "email"); const std::string ChallengeEmail::NEED_CODE = "need-code"; const std::string ChallengeEmail::WRONG_CODE = "wrong-code"; -const std::string ChallengeEmail::INVALID_EMAIL = "invalid-email"; const std::string ChallengeEmail::PARAMETER_KEY_EMAIL = "email"; const std::string ChallengeEmail::PARAMETER_KEY_CODE = "code"; @@ -50,13 +49,9 @@ ChallengeEmail::handleChallengeRequest(const Block& params, ca::RequestState& re if (request.status == Status::BEFORE_CHALLENGE) { // for the first time, init the challenge std::string emailAddress = readString(params.get(tlv::ParameterValue)); - if (!isValidEmailAddress(emailAddress)) { - return returnWithNewChallengeStatus(request, INVALID_EMAIL, JsonSection(), m_maxAttemptTimes - 1, - m_secretLifetime); - } auto lastComponentRequested = readString(request.cert.getIdentity().get(-1)); if (lastComponentRequested != emailAddress) { - NDN_LOG_TRACE("Email and requested name do not match. Email " << emailAddress << "requested last component " + NDN_LOG_TRACE("Email and requested name do not match. Email " << emailAddress << " requested last component " << lastComponentRequested); } std::string emailCode = generateSecretCode(); @@ -96,8 +91,8 @@ ChallengeEmail::handleChallengeRequest(const Block& params, ca::RequestState& re } else { // run out times - NDN_LOG_TRACE("Wrong secret code provided. Ran out tires. Challenge failed."); - return returnWithError(request, ErrorCode::OUT_OF_TRIES, "Ran out tires."); + NDN_LOG_TRACE("Wrong secret code provided. Ran out of tries. Challenge failed."); + return returnWithError(request, ErrorCode::OUT_OF_TRIES, "Ran out of tries."); } } } @@ -112,9 +107,6 @@ ChallengeEmail::getRequestedParameterList(Status status, const std::string& chal if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") { result.emplace(PARAMETER_KEY_EMAIL, "Please input your email address"); } - else if (status == Status::CHALLENGE && challengeStatus == INVALID_EMAIL) { - result.emplace(PARAMETER_KEY_EMAIL, "Invalid email, please try again"); - } else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) { result.emplace(PARAMETER_KEY_CODE, "Please input your verification code"); } @@ -176,8 +168,10 @@ ChallengeEmail::sendEmail(const std::string& emailAddress, const std::string& se if (child.exit_code() != 0) { NDN_LOG_TRACE("EmailSending Script " + m_sendEmailScript + " fails."); } - NDN_LOG_TRACE("EmailSending Script " + m_sendEmailScript + - " was executed successfully with return value 0."); + else { + NDN_LOG_TRACE("EmailSending Script " + m_sendEmailScript + + " was executed successfully with return value 0."); + } } } // namespace ndncert diff --git a/src/challenge/challenge-email.hpp b/src/challenge/challenge-email.hpp index c5d76de..6de8216 100644 --- a/src/challenge/challenge-email.hpp +++ b/src/challenge/challenge-email.hpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -44,7 +44,6 @@ namespace ndncert { * * Failure info when application fails: * FAILURE_MAXRETRY: When run out retry times. - * FAILURE_INVALID_EMAIL: When the email is invalid. * FAILURE_TIMEOUT: When the secret lifetime expires. */ class ChallengeEmail : public ChallengeModule @@ -69,7 +68,6 @@ class ChallengeEmail : public ChallengeModule // challenge status static const std::string NEED_CODE; static const std::string WRONG_CODE; - static const std::string INVALID_EMAIL; // challenge parameters static const std::string PARAMETER_KEY_EMAIL; static const std::string PARAMETER_KEY_CODE; diff --git a/src/detail/ca-configuration.cpp b/src/detail/ca-configuration.cpp index a6d26a0..55b8a7c 100644 --- a/src/detail/ca-configuration.cpp +++ b/src/detail/ca-configuration.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -53,11 +53,24 @@ CaConfig::load(const std::string& fileName) auto caPrefixStr = item.second.get(CONFIG_CA_PREFIX, ""); auto caCertStr = item.second.get(CONFIG_CERTIFICATE, ""); if (caCertStr == "") { - NDN_THROW(std::runtime_error("Redirect-to item's ca-prefix or certificate cannot be empty.")); + NDN_THROW(std::runtime_error("Redirect-to item's certificate cannot be empty.")); } std::istringstream ss(caCertStr); auto caCert = ndn::io::load(ss); - redirection.push_back(caCert); + if (caPrefixStr != "" && Name(caPrefixStr) != caCert->getIdentity()) { + NDN_THROW(std::runtime_error("Redirect-to item's prefix and certificate does not match.")); + } + + auto policyType = item.second.get(CONFIG_REDIRECTION_POLICY_TYPE, ""); + auto policyParam = item.second.get(CONFIG_REDIRECTION_POLICY_PARAM, ""); + if (policyType.empty()) { + NDN_THROW(std::runtime_error("Redirect-to policy type expected but not provided.")); + } + auto policy = RedirectionPolicy::createPolicyFunc(policyType, policyParam); + if (policy == nullptr) { + NDN_THROW(std::runtime_error("Error on creating redirection policy")); + } + redirection.emplace_back(caCert, std::move(policy)); } } // parse name assignment if appears diff --git a/src/detail/ca-configuration.hpp b/src/detail/ca-configuration.hpp index 2a2a9ff..0a02777 100644 --- a/src/detail/ca-configuration.hpp +++ b/src/detail/ca-configuration.hpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -21,8 +21,9 @@ #ifndef NDNCERT_DETAIL_CA_CONFIGURATION_HPP #define NDNCERT_DETAIL_CA_CONFIGURATION_HPP -#include "detail/ca-profile.hpp" #include "name-assignment/assignment-func.hpp" +#include "redirection/redirection-policy.hpp" +#include "ca-profile.hpp" namespace ndncert { namespace ca { @@ -66,7 +67,7 @@ class CaConfig /** * @brief Used for CA redirection */ - std::vector> redirection; + std::vector, std::unique_ptr>> redirection; /** * @brief Name Assignment Functions */ diff --git a/src/detail/ca-profile.hpp b/src/detail/ca-profile.hpp index 0592be5..74af5c0 100644 --- a/src/detail/ca-profile.hpp +++ b/src/detail/ca-profile.hpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -37,6 +37,8 @@ const std::string CONFIG_CHALLENGE = "challenge"; const std::string CONFIG_CERTIFICATE = "certificate"; const std::string CONFIG_REDIRECTION = "redirect-to"; const std::string CONFIG_NAME_ASSIGNMENT = "name-assignment"; +const std::string CONFIG_REDIRECTION_POLICY_TYPE = "policy-type"; +const std::string CONFIG_REDIRECTION_POLICY_PARAM = "policy-param"; class CaProfile { diff --git a/src/detail/challenge-encoder.cpp b/src/detail/challenge-encoder.cpp index 5d9d46b..0f85fdc 100644 --- a/src/detail/challenge-encoder.cpp +++ b/src/detail/challenge-encoder.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -59,31 +59,62 @@ challengetlv::decodeDataContent(const Block& contentBlock, requester::Request& s auto data = ndn::makeBinaryBlock(tlv::EncryptedPayload, result.data(), result.size()); data.parse(); - state.m_status = statusFromBlock(data.get(tlv::Status)); - if (data.find(tlv::ChallengeStatus) != data.elements_end()) { - state.m_challengeStatus = readString(data.get(tlv::ChallengeStatus)); - } - if (data.find(tlv::RemainingTries) != data.elements_end()) { - state.m_remainingTries = readNonNegativeInteger(data.get(tlv::RemainingTries)); - } - if (data.find(tlv::RemainingTime) != data.elements_end()) { - state.m_freshBefore = time::system_clock::now() + - time::seconds(readNonNegativeInteger(data.get(tlv::RemainingTime))); - } - if (data.find(tlv::IssuedCertName) != data.elements_end()) { - Block issuedCertNameBlock = data.get(tlv::IssuedCertName); - state.m_issuedCertName = Name(issuedCertNameBlock.blockFromValue()); - } - if (data.find(tlv::ParameterKey) != data.elements_end() && - readString(data.get(tlv::ParameterKey)) == "nonce") { - if (data.find(tlv::ParameterKey) == data.elements_end()) { - NDN_THROW(std::runtime_error("Parameter Key found, but no value found")); + int numStatus = 0; + bool lookingForNonce = false; + for (const auto &item : data.elements()) { + if (!lookingForNonce) { + switch (item.type()) { + case tlv::Status: + state.m_status = statusFromBlock(data.get(tlv::Status)); + numStatus++; + break; + case tlv::ChallengeStatus: + state.m_challengeStatus = readString(item); + break; + case tlv::RemainingTries: + state.m_remainingTries = readNonNegativeInteger(item); + break; + case tlv::RemainingTime: + state.m_freshBefore = time::system_clock::now() + + time::seconds(readNonNegativeInteger(item)); + break; + case tlv::IssuedCertName: + state.m_issuedCertName = Name(item.blockFromValue()); + break; + case tlv::ParameterKey: + if (readString(item) == "nonce") { + lookingForNonce = true; + } + else { + NDN_THROW(std::runtime_error("Unknown Parameter: " + readString(item))); + } + break; + default: + if (ndn::tlv::isCriticalType(item.type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(item.type()))); + } + else { + //ignore + } + break; + } } - Block nonceBlock = data.get(tlv::ParameterValue); - if (nonceBlock.value_size() != 16) { - NDN_THROW(std::runtime_error("Wrong nonce length")); + else { + if (item.type() == tlv::ParameterValue) { + lookingForNonce = false; + if (item.value_size() != 16) { + NDN_THROW(std::runtime_error("Wrong nonce length")); + } + memcpy(state.m_nonce.data(), item.value(), 16); + } + else { + NDN_THROW(std::runtime_error("Parameter Key found, but no value found")); + } } - memcpy(state.m_nonce.data(), nonceBlock.value(), 16); + } + if (numStatus != 1) { + NDN_THROW(std::runtime_error("number of status block is not equal to 1; there are " + + std::to_string(numStatus) + " status blocks")); } } diff --git a/src/detail/error-encoder.cpp b/src/detail/error-encoder.cpp index e1e4357..990ce84 100644 --- a/src/detail/error-encoder.cpp +++ b/src/detail/error-encoder.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -20,6 +20,8 @@ #include "detail/error-encoder.hpp" +NDN_LOG_INIT(ndncert.encode.error); + namespace ndncert { Block @@ -35,12 +37,44 @@ errortlv::encodeDataContent(ErrorCode errorCode, const std::string& description) std::tuple errortlv::decodefromDataContent(const Block& block) { - block.parse(); - if (block.find(tlv::ErrorCode) == block.elements_end()) { + try { + block.parse(); + int codeCount = 0; + int infoCount = 0; + int otherCriticalCount = 0; + ErrorCode error; + std::string errorInfo; + for (const auto& item : block.elements()) { + if (item.type() == tlv::ErrorCode) { + error = static_cast(readNonNegativeInteger(block.get(tlv::ErrorCode))); + codeCount ++; + } + else if (item.type() == tlv::ErrorInfo) { + errorInfo = readString(block.get(tlv::ErrorInfo)); + infoCount ++; + } + else if (ndn::tlv::isCriticalType(item.type())) { + otherCriticalCount ++; + } + else { + //ignore + } + } + if (codeCount == 0 && infoCount == 0) { + return std::make_tuple(ErrorCode::NO_ERROR, ""); + } + if (codeCount != 1 || infoCount != 1) { + NDN_THROW(std::runtime_error("Error TLV contains " + std::to_string(codeCount) + " error code(s) and " + + std::to_string(infoCount) + "error info(s), instead of expected 1 times each.")); + } + if (otherCriticalCount > 0) { + NDN_THROW(std::runtime_error("Unknown Critical TLV type in error packet")); + } + return std::make_tuple(error, errorInfo); + } catch (const std::exception& e) { + NDN_LOG_ERROR("[errortlv::DecodeFromDataContent] Exception in error message decoding: " << e.what()); return std::make_tuple(ErrorCode::NO_ERROR, ""); } - ErrorCode error = static_cast(readNonNegativeInteger(block.get(tlv::ErrorCode))); - return std::make_tuple(error, readString(block.get(tlv::ErrorInfo))); } } // namespace ndncert diff --git a/src/detail/error-encoder.hpp b/src/detail/error-encoder.hpp index 3b17353..cd136cf 100644 --- a/src/detail/error-encoder.hpp +++ b/src/detail/error-encoder.hpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * diff --git a/src/detail/info-encoder.cpp b/src/detail/info-encoder.cpp index e6e6581..9331f1f 100644 --- a/src/detail/info-encoder.cpp +++ b/src/detail/info-encoder.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -20,6 +20,8 @@ #include "detail/info-encoder.hpp" +NDN_LOG_INIT(ndncert.encode.info); + namespace ndncert { Block @@ -41,36 +43,41 @@ infotlv::encodeDataContent(const CaProfile& caConfig, const Certificate& certifi content.push_back(ndn::makeNonNegativeIntegerBlock(tlv::MaxValidityPeriod, caConfig.maxValidityPeriod.count())); content.push_back(makeNestedBlock(tlv::CaCertificate, certificate)); content.encode(); + NDN_LOG_TRACE("Encoding INFO packet with certificate " << certificate.getFullName()); return content; } CaProfile -infotlv::decodeDataContent(const Block& block) -{ +infotlv::decodeDataContent(const Block& block) { CaProfile result; block.parse(); - for (auto const& item : block.elements()) { + for (auto const &item : block.elements()) { switch (item.type()) { - case tlv::CaPrefix: - item.parse(); - result.caPrefix.wireDecode(item.get(ndn::tlv::Name)); - break; - case tlv::CaInfo: - result.caInfo = readString(item); - break; - case tlv::ParameterKey: - result.probeParameterKeys.push_back(readString(item)); - break; - case tlv::MaxValidityPeriod: - result.maxValidityPeriod = time::seconds(readNonNegativeInteger(item)); - break; - case tlv::CaCertificate: - item.parse(); - result.cert = std::make_shared(item.get(ndn::tlv::Data)); - break; - default: - continue; - break; + case tlv::CaPrefix: + item.parse(); + result.caPrefix.wireDecode(item.get(ndn::tlv::Name)); + break; + case tlv::CaInfo: + result.caInfo = readString(item); + break; + case tlv::ParameterKey: + result.probeParameterKeys.push_back(readString(item)); + break; + case tlv::MaxValidityPeriod: + result.maxValidityPeriod = time::seconds(readNonNegativeInteger(item)); + break; + case tlv::CaCertificate: + item.parse(); + result.cert = std::make_shared(item.get(ndn::tlv::Data)); + break; + default: + if (ndn::tlv::isCriticalType(item.type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(item.type()))); + } + else { + //ignore + } + break; } } return result; diff --git a/src/detail/probe-encoder.cpp b/src/detail/probe-encoder.cpp index bf51438..13b040e 100644 --- a/src/detail/probe-encoder.cpp +++ b/src/detail/probe-encoder.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -35,14 +35,21 @@ probetlv::encodeApplicationParameters(const std::multimap -probetlv::decodeApplicationParameters(const Block& block) -{ +probetlv::decodeApplicationParameters(const Block& block) { std::multimap result; block.parse(); - for (size_t i = 0; i < block.elements().size() - 1; i++) { - if (block.elements()[i].type() == tlv::ParameterKey && block.elements()[i + 1].type() == tlv::ParameterValue) { - result.emplace(readString(block.elements().at(i)), readString(block.elements().at(i + 1))); - i ++; + const auto& elements = block.elements(); + for (size_t i = 0; i < elements.size(); i++) { + if (i + 1 < elements.size() && elements[i].type() == tlv::ParameterKey && + elements[i + 1].type() == tlv::ParameterValue) { + result.emplace(readString(elements.at(i)), readString(elements.at(i + 1))); + i++; + } + else if (ndn::tlv::isCriticalType(elements[i].type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(elements[i].type()))); + } + else { + //ignore } } return result; @@ -50,7 +57,7 @@ probetlv::decodeApplicationParameters(const Block& block) Block probetlv::encodeDataContent(const std::vector& identifiers, optional maxSuffixLength, - std::vector> redirectionItems) + std::vector redirectionItems) { Block content(ndn::tlv::Content); for (const auto& name : identifiers) { @@ -61,9 +68,11 @@ probetlv::encodeDataContent(const std::vector& identifiers, optionalgetFullName())); + content.push_back(makeNestedBlock(tlv::ProbeRedirect, item)); } + content.encode(); return content; } @@ -71,8 +80,7 @@ probetlv::encodeDataContent(const std::vector& identifiers, optional>& availableNames, - std::vector& availableRedirection) -{ + std::vector& availableRedirection) { block.parse(); for (const auto& item : block.elements()) { if (item.type() == tlv::ProbeResponse) { @@ -89,15 +97,27 @@ probetlv::decodeDataContent(const Block& block, else if (subBlock.type() == tlv::MaxSuffixLength) { maxSuffixLength = readNonNegativeInteger(subBlock); } + else if (ndn::tlv::isCriticalType(subBlock.type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type in probe name item: " + std::to_string(subBlock.type()))); + } + else { + //ignore + } } if (elementName.empty()) { NDN_THROW(std::runtime_error("Invalid probe format")); } availableNames.emplace_back(elementName, maxSuffixLength); } - if (item.type() == tlv::ProbeRedirect) { + else if (item.type() == tlv::ProbeRedirect) { availableRedirection.emplace_back(Name(item.blockFromValue())); } + else if (ndn::tlv::isCriticalType(item.type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(item.type()))); + } + else { + //ignore + } } } diff --git a/src/detail/probe-encoder.hpp b/src/detail/probe-encoder.hpp index 6afe083..223c61b 100644 --- a/src/detail/probe-encoder.hpp +++ b/src/detail/probe-encoder.hpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -38,8 +38,7 @@ decodeDataContent(const Block& block, std::vector>& availab Block encodeDataContent(const std::vector& identifiers, optional maxSuffixLength = nullopt, - std::vector> redirectionItems = - std::vector>()); + std::vector redirectionItems = std::vector()); std::multimap decodeApplicationParameters(const Block& block); diff --git a/src/detail/request-encoder.cpp b/src/detail/request-encoder.cpp index 30e2523..fde2d86 100644 --- a/src/detail/request-encoder.cpp +++ b/src/detail/request-encoder.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -51,20 +51,35 @@ requesttlv::decodeApplicationParameters(const Block& payload, RequestType reques { payload.parse(); - const auto& ecdhBlock = payload.get(tlv::EcdhPub); - ecdhPub.resize(ecdhBlock.value_size()); - std::memcpy(ecdhPub.data(), ecdhBlock.value(), ecdhBlock.value_size()); - + int ecdhPubCount = 0; Block requestPayload; - if (requestType == RequestType::NEW) { - requestPayload = payload.get(tlv::CertRequest); - } - else if (requestType == RequestType::REVOKE) { - requestPayload = payload.get(tlv::CertToRevoke); + int requestPayloadCount = 0; + for (const auto &item : payload.elements()) { + if (item.type() == tlv::EcdhPub) { + ecdhPub.resize(item.value_size()); + std::memcpy(ecdhPub.data(), item.value(), item.value_size()); + ecdhPubCount++; + } + else if ((requestType == RequestType::NEW && item.type() == tlv::CertRequest) || + (requestType == RequestType::REVOKE && item.type() == tlv::CertToRevoke)) { + requestPayload = item; + requestPayloadCount++; + requestPayload.parse(); + clientCert = std::make_shared(requestPayload.get(ndn::tlv::Data)); + } + else if (ndn::tlv::isCriticalType(item.type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(item.type()))); + } + else { + //ignore + } } - requestPayload.parse(); - clientCert = std::make_shared(requestPayload.get(ndn::tlv::Data)); + if (ecdhPubCount != 1 || requestPayloadCount != 1) { + NDN_THROW(std::runtime_error("Error TLV contains " + std::to_string(ecdhPubCount) + " ecdh public param(s) and " + + std::to_string(requestPayloadCount) + + "request payload(s), instead of expected 1 times each.")); + } } Block @@ -85,25 +100,38 @@ requesttlv::encodeDataContent(const std::vector & ecdhKey, const std::a std::list requesttlv::decodeDataContent(const Block& content, std::vector & ecdhKey, - std::array& salt, RequestId& requestId) -{ + std::array& salt, RequestId& requestId) { + std::list challenges; content.parse(); - - const auto& ecdhBlock = content.get(tlv::EcdhPub); - ecdhKey.resize(ecdhBlock.value_size()); - std::memcpy(ecdhKey.data(), ecdhBlock.value(), ecdhBlock.value_size()); - - const auto& saltBlock = content.get(tlv::Salt); - std::memcpy(salt.data(), saltBlock.value(), saltBlock.value_size()); - - const auto& requestIdBlock = content.get(tlv::RequestId); - std::memcpy(requestId.data(), requestIdBlock.value(), requestIdBlock.value_size()); - - std::list challenges; - for (auto const& element : content.elements()) { + int ecdhPubCount = 0, saltCount = 0, requestIdCount = 0; + for (auto const &element : content.elements()) { if (element.type() == tlv::Challenge) { challenges.push_back(readString(element)); } + else if (element.type() == tlv::EcdhPub) { + ecdhKey.resize(element.value_size()); + std::memcpy(ecdhKey.data(), element.value(), element.value_size()); + ecdhPubCount++; + } + else if (element.type() == tlv::Salt) { + std::memcpy(salt.data(), element.value(), element.value_size()); + saltCount++; + } + else if (element.type() == tlv::RequestId) { + std::memcpy(requestId.data(), element.value(), element.value_size()); + requestIdCount++; + } + else if (ndn::tlv::isCriticalType(element.type())) { + NDN_THROW(std::runtime_error("Unrecognized TLV Type: " + std::to_string(element.type()))); + } + else { + //ignore + } + } + if (ecdhPubCount != 1 || saltCount != 1 || requestIdCount != 1) { + NDN_THROW(std::runtime_error("Error TLV contains " + std::to_string(ecdhPubCount) + " ecdh public param(s), " + + std::to_string(saltCount) + " salt(s) and " + std::to_string(requestIdCount) + + "request id(s), instead of expected 1 times each.")); } return challenges; } diff --git a/src/name-assignment/assignment-email.cpp b/src/name-assignment/assignment-email.cpp new file mode 100644 index 0000000..685a820 --- /dev/null +++ b/src/name-assignment/assignment-email.cpp @@ -0,0 +1,62 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#include "assignment-email.hpp" + +namespace ndncert { + +NDNCERT_REGISTER_FUNCFACTORY(AssignmentEmail, "email"); + +AssignmentEmail::AssignmentEmail(const std::string& format) + : NameAssignmentFunc(format) +{ +} + +std::vector +AssignmentEmail::assignName(const std::multimap& params) +{ + std::vector resultList; + Name result; + if (!m_nameFormat.empty() && params.count("email") > 0) { + const std::string& email = params.begin()->second; + auto formatIter = m_nameFormat.begin(); + size_t emailSplit = email.rfind("@"); + std::string domain = "." + email.substr(emailSplit + 1); + + if (emailSplit != std::string::npos && emailSplit > 0) { + size_t domainSplit = domain.rfind("."); + while (domainSplit != std::string::npos) { + if (formatIter != m_nameFormat.end() && domain.substr(domainSplit + 1) == *formatIter) { + formatIter++; + } + else { + result.push_back(domain.substr(domainSplit + 1).c_str()); + } + domain = domain.substr(0, domainSplit); + domainSplit = domain.rfind("."); + } + result.push_back(email.substr(0, emailSplit).c_str()); + resultList.push_back(std::move(result)); + } + } + return resultList; +} + +} // namespace ndncert diff --git a/src/name-assignment/assignment-email.hpp b/src/name-assignment/assignment-email.hpp new file mode 100644 index 0000000..c0bb330 --- /dev/null +++ b/src/name-assignment/assignment-email.hpp @@ -0,0 +1,42 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#ifndef NDNCERT_ASSIGNMENT_EMAIL_HPP +#define NDNCERT_ASSIGNMENT_EMAIL_HPP + +#include "assignment-func.hpp" + +namespace ndncert { + +/** + * assign names base on client probe parameter + */ +class AssignmentEmail : public NameAssignmentFunc +{ +public: + explicit AssignmentEmail(const std::string& format = ""); + + std::vector + assignName(const std::multimap& params) override; +}; + +} // namespace ndncert + +#endif // NDNCERT_ASSIGNMENT_EMAIL_HPP diff --git a/src/name-assignment/assignment-param.cpp b/src/name-assignment/assignment-param.cpp index 956b3d8..e1961e7 100644 --- a/src/name-assignment/assignment-param.cpp +++ b/src/name-assignment/assignment-param.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -35,13 +35,17 @@ AssignmentParam::assignName(const std::multimap& param std::vector resultList; Name result; for (const auto& item : m_nameFormat) { - auto it = std::find_if(params.begin(), params.end(), - [&](const std::tuple& e) { return std::get<0>(e) == item; }); - if (it != params.end() && !it->second.empty()) { - result.append(it->second); + if (item.size() >= 2 && item[0] == '"' && item[item.size() - 1] == '"') { + result.append(item.substr(1, item.size() - 2)); } else { - return resultList; + auto it = params.find(item); + if (it != params.end() && !it->second.empty()) { + result.append(it->second); + } + else { + return resultList; // empty + } } } resultList.push_back(std::move(result)); diff --git a/src/redirection/redirection-email.cpp b/src/redirection/redirection-email.cpp new file mode 100644 index 0000000..863eb91 --- /dev/null +++ b/src/redirection/redirection-email.cpp @@ -0,0 +1,46 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#include "redirection-email.hpp" +#include + +namespace ndncert { + +NDNCERT_REGISTER_POLICY_FACTORY(RedirectionEmail, "email"); + +RedirectionEmail::RedirectionEmail(const std::string& format) + : RedirectionPolicy(format) +{ + m_domain = format; +} + +bool +RedirectionEmail::isRedirecting(const std::multimap& params) +{ + for (auto it = params.find("email"); it != params.end() && it->first == "email"; it++) { + auto i = it->second.rfind('@'); + if (i != std::string::npos && it->second.substr(i + 1) == m_domain) { + return true; + } + } + return false; +} + +} // namespace ndncert diff --git a/src/redirection/redirection-email.hpp b/src/redirection/redirection-email.hpp new file mode 100644 index 0000000..9a338ef --- /dev/null +++ b/src/redirection/redirection-email.hpp @@ -0,0 +1,45 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#ifndef NDNCERT_REDIRECTION_EMAIL_HPP +#define NDNCERT_REDIRECTION_EMAIL_HPP + +#include "redirection-policy.hpp" + +namespace ndncert { + +/** + * assign names base on client probe parameter + */ +class RedirectionEmail : public RedirectionPolicy +{ +public: + explicit RedirectionEmail(const std::string& format = ""); + + bool + isRedirecting(const std::multimap& params) override; + +private: + std::string m_domain; +}; + +} // namespace ndncert + +#endif // NDNCERT_REDIRECTION_EMAIL_HPP diff --git a/src/redirection/redirection-param.cpp b/src/redirection/redirection-param.cpp new file mode 100644 index 0000000..d74d105 --- /dev/null +++ b/src/redirection/redirection-param.cpp @@ -0,0 +1,63 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#include "redirection-param.hpp" +#include + +namespace ndncert { + +NDNCERT_REGISTER_POLICY_FACTORY(RedirectionParam, "param"); + +RedirectionParam::RedirectionParam(const std::string& format) + : RedirectionPolicy(format) +{ + if (format.empty()) { + return; + } + std::vector strs; + boost::split(strs,format,boost::is_any_of("&")); + for (const auto& s : strs) { + auto i = s.find('='); + if (i == std::string::npos) { + NDN_THROW(std::runtime_error("Redirection param format: no '=' in format piece")); + } + m_format.emplace(s.substr(0, i), s.substr(i + 1)); + } +} + +bool +RedirectionParam::isRedirecting(const std::multimap& params) +{ + for (const auto& p : m_format) { + bool found = false; + for (auto it = params.find(p.first); it != params.end() && it->first == p.first; it ++) { + if (it->second == p.second) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; +} + +} // namespace ndncert diff --git a/src/redirection/redirection-param.hpp b/src/redirection/redirection-param.hpp new file mode 100644 index 0000000..d067a1f --- /dev/null +++ b/src/redirection/redirection-param.hpp @@ -0,0 +1,45 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#ifndef NDNCERT_REDIRECTION_PARAM_HPP +#define NDNCERT_REDIRECTION_PARAM_HPP + +#include "redirection-policy.hpp" + +namespace ndncert { + +/** + * assign names base on client probe parameter + */ +class RedirectionParam : public RedirectionPolicy +{ +public: + explicit RedirectionParam(const std::string& format = ""); + + bool + isRedirecting(const std::multimap& params) override; + +private: + std::map m_format; +}; + +} // namespace ndncert + +#endif // NDNCERT_REDIRECTION_PARAM_HPP diff --git a/src/redirection/redirection-policy.cpp b/src/redirection/redirection-policy.cpp new file mode 100644 index 0000000..88aef3e --- /dev/null +++ b/src/redirection/redirection-policy.cpp @@ -0,0 +1,40 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#include "redirection-policy.hpp" + +namespace ndncert { + +std::unique_ptr +RedirectionPolicy::createPolicyFunc(const std::string& policyType, const std::string& format) +{ + PolicyFactory& factory = getFactory(); + auto i = factory.find(policyType); + return i == factory.end() ? nullptr : i->second(format); +} + +RedirectionPolicy::PolicyFactory& +RedirectionPolicy::getFactory() +{ + static PolicyFactory factory; + return factory; +} + +} // namespace ndncert diff --git a/src/redirection/redirection-policy.hpp b/src/redirection/redirection-policy.hpp new file mode 100644 index 0000000..cba0cd8 --- /dev/null +++ b/src/redirection/redirection-policy.hpp @@ -0,0 +1,81 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#ifndef NDNCERT_REDIRECTION_POLICY_HPP +#define NDNCERT_REDIRECTION_POLICY_HPP + +#include "detail/ca-request-state.hpp" + +#include + +namespace ndncert { + +class RedirectionPolicy : boost::noncopyable +{ +protected: + explicit RedirectionPolicy(const std::string& format = "") {} + +public: + virtual ~RedirectionPolicy() = default; + + /** + * @brief The Redirection Policy provided by the CA operator to decide if redirection is suitable. + * + * + * @param vector A list of parameter key-value pair from probe. + * @return a boolean that is true if the provided params conform to the configured redirection policy. + */ + virtual bool + isRedirecting(const std::multimap& params) = 0; + +public: + template + static void + registerRedirectionPolicy(const std::string& typeName) + { + PolicyFactory& factory = getFactory(); + BOOST_ASSERT(factory.count(typeName) == 0); + factory[typeName] = [](const std::string& format) { return std::make_unique(format); }; + } + + static std::unique_ptr + createPolicyFunc(const std::string& policyType, const std::string& format = ""); + +private: + typedef std::function(const std::string&)> FactoryCreateFunc; + typedef std::map PolicyFactory; + + static PolicyFactory& + getFactory(); +}; + +#define NDNCERT_REGISTER_POLICY_FACTORY(C, T) \ + static class NdnCert##C##PolicyFactoryRegistrationClass \ + { \ + public: \ + NdnCert##C##PolicyFactoryRegistrationClass() \ + { \ + ::ndncert::RedirectionPolicy::registerRedirectionPolicy(T); \ + } \ + } g_NdnCert##C##RedirectionPolicyRegistrationVariable + +} // namespace ndncert + +#endif // NDNCERT_REDIRECTION_POLICY_HPP diff --git a/src/requester-request.cpp b/src/requester-request.cpp index 6ab56ea..5d9896f 100644 --- a/src/requester-request.cpp +++ b/src/requester-request.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * diff --git a/systemd/ndncert-ca.service.in b/systemd/ndncert-ca.service.in index 94ac006..97c81d8 100644 --- a/systemd/ndncert-ca.service.in +++ b/systemd/ndncert-ca.service.in @@ -1,14 +1,41 @@ [Unit] Description=Certificate Management Identity Management Service for NDN +BindsTo=nfd.service +After=nfd.service [Service] Environment=HOME=%S/ndncert-ca ExecStart=@BINDIR@/ndncert-ca-server Restart=on-failure RestartPreventExitStatus=2 -RestartSec=5 User=ndn +CapabilityBoundingSet= +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +PrivateDevices=yes +PrivateTmp=yes +PrivateUsers=yes +ProtectControlGroups=yes +ProtectHome=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +# systemd older than v232 doesn't support a value of "strict" for ProtectSystem, +# so it will ignore that line and use ProtectSystem=full; with newer systemd, +# the latter assignment is recognized and takes precedence, resulting in an +# effective setting of ProtectSystem=strict +ProtectSystem=full +ProtectSystem=strict +RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6 AF_PACKET +RestrictNamespaces=yes +RestrictRealtime=yes +StateDirectory=ndncert-ca +SystemCallArchitectures=native +SystemCallErrorNumber=EPERM +SystemCallFilter=~@aio @chown @clock @cpu-emulation @debug @keyring @module @mount @obsolete @privileged @raw-io @reboot @resources @setuid @swap + +# Dependency [Install] WantedBy=multi-user.target -Alias=ndncert.service \ No newline at end of file +WantedBy=nfd.service \ No newline at end of file diff --git a/tests/unit-tests/ca-module.t.cpp b/tests/unit-tests/ca-module.t.cpp index d4a733d..2a9640b 100644 --- a/tests/unit-tests/ca-module.t.cpp +++ b/tests/unit-tests/ca-module.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -211,8 +211,8 @@ BOOST_AUTO_TEST_CASE(HandleProbeRedirection) } } BOOST_CHECK_EQUAL(redirectionItems.size(), 2); - BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/site1"); - BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/site1"); + BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirectionItems[0].getPrefix(-1)), "/ndn/edu/ucla"); + BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirectionItems[1].getPrefix(-1)), "/ndn/edu/ucla/cs/irl"); }); face.receive(interest); advanceClocks(time::milliseconds(20), 60); diff --git a/tests/unit-tests/challenge-email.t.cpp b/tests/unit-tests/challenge-email.t.cpp index 92fb45b..1044660 100644 --- a/tests/unit-tests/challenge-email.t.cpp +++ b/tests/unit-tests/challenge-email.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -93,30 +93,6 @@ BOOST_AUTO_TEST_CASE(OnChallengeRequestWithEmail) std::remove("tmp.txt"); } -BOOST_AUTO_TEST_CASE(OnChallengeRequestWithInvalidEmail) -{ - auto identity = addIdentity(Name("/ndn/site1")); - auto key = identity.getDefaultKey(); - auto cert = key.getDefaultCertificate(); - RequestId requestId = {{101}}; - ca::RequestState request; - request.caPrefix = Name("/ndn/site1"); - request.requestId = requestId; - request.requestType = RequestType::NEW; - request.cert = cert; - - Block paramTLV = ndn::makeEmptyBlock(tlv::EncryptedPayload); - paramTLV.push_back(ndn::makeStringBlock(tlv::ParameterKey, ChallengeEmail::PARAMETER_KEY_EMAIL)); - paramTLV.push_back(ndn::makeStringBlock(tlv::ParameterValue, "zhiyi@cs")); - - ChallengeEmail challenge; - challenge.handleChallengeRequest(paramTLV, request); - - BOOST_CHECK_EQUAL(request.challengeType, "email"); - BOOST_CHECK_EQUAL(request.challengeState->challengeStatus, ChallengeEmail::INVALID_EMAIL); - BOOST_CHECK_EQUAL(request.challengeState->remainingTries, 2); -} - BOOST_AUTO_TEST_CASE(OnChallengeRequestWithCode) { auto identity = addIdentity(Name("/ndn/site1")); diff --git a/tests/unit-tests/config-files/config-ca-5 b/tests/unit-tests/config-files/config-ca-5 index f867534..5d306aa 100644 --- a/tests/unit-tests/config-files/config-ca-5 +++ b/tests/unit-tests/config-files/config-ca-5 @@ -15,11 +15,15 @@ [ { "ca-prefix": "/ndn/edu/ucla", - "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F" + "certificate": "Bv0BNQcvCANuZG4IA2VkdQgEdWNsYQgDS0VZCAhtCJjCeE5aEwgEc2VsZjYIAAABf1ePw8kUCRgBAhkEADbugBVbMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEwrhu4gD0eba7jbVqg1qfwuRj2JSqOfnwdiOlholvhCGpdXHpqg5o68ajADQPL9S555uvfabbFnPhv86X/Diy5hZQGwEDHCEHHwgDbmRuCANlZHUIBHVjbGEIA0tFWQgIbQiYwnhOWhP9AP0m/QD+DzE5NzAwMTAxVDAwMDAwMP0A/w8yMDQyMDIyOFQwMDUxNTMXSDBGAiEA11i8sGwf83hd+IQ2vve+Ax1O7zZeV8cG6FAXvXFQ0kACIQDAvqq0CRAYYJ/RFLW21wNGJf1Rf3OgFyGEKpLjnRkxaw==", + "policy-type": "param", + "policy-param": "" }, { - "ca-prefix": "/ndn/edu/irl", - "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F" + "ca-prefix": "/ndn/edu/ucla/cs/irl", + "certificate": "Bv0BRQc4CANuZG4IA2VkdQgEdWNsYQgCY3MIA2lybAgDS0VZCAgWVGa5Tzd9WggEc2VsZjYIAAABf1eQ1LoUCRgBAhkEADbugBVbMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7hBKT9GapKRII3LT9q0kY5RXEE9Cu9B2Pg/E4Mndbqr3nbnMmm+SUAeIcrnTQa4c9ri8oCLkTesXsW0Tr8oTuhZZGwEDHCoHKAgDbmRuCANlZHUIBHVjbGEIAmNzCANpcmwIA0tFWQgIFlRmuU83fVr9AP0m/QD+DzE5NzAwMTAxVDAwMDAwMP0A/w8yMDQyMDIyOFQwMDUzMDMXRjBEAiA9Q/FjffFLasMfr7MIQY/KBBQScNKYyrEyphz4wOcQjAIgLf14XL8LaqqUyfBkwQXeCv3pipsnZw5BFhv8c5UCLVE=", + "policy-type": "param", + "policy-param": "" } ], "name-assignment": diff --git a/tests/unit-tests/config-files/config-client-1 b/tests/unit-tests/config-files/config-client-1 index 20daad1..79d9519 100644 --- a/tests/unit-tests/config-files/config-client-1 +++ b/tests/unit-tests/config-files/config-client-1 @@ -10,11 +10,11 @@ [ { "probe-parameter-key": "email" } ], - "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F" + "certificate": "Bv0BKwcrCANuZG4IBXNpdGUxCANLRVkICEKyYEYHiBwyCARzZWxmNggAAAF/V5V9QhQJGAECGQQANu6AFVswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARRaZbFLRSnL1fmj8X3hInCCPy4qe17QujMMYq8qe+CKqV+OjexhrUvpwRDImRZOgXLCjOTyYnW3wxlxskTz8Y3FkwbAQMcHQcbCANuZG4IBXNpdGUxCANLRVkICEKyYEYHiBwy/QD9Jv0A/g8xOTcwMDEwMVQwMDAwMDD9AP8PMjA0MjAyMjhUMDA1ODA5F0YwRAIgFtFP0WocLQCtbwMTnqNtnCDmu62EJyC4uuCZ4Q/Wb8UCIGHb3e4St78378py81GjEZd/2L/aGbE3vbYQIiNxIYPN" }, { "ca-prefix": "/ndn/edu/ucla/zhiyi", - "certificate": "Bv0CJAcsCANuZG4IBXNpdGUxCANLRVkICBG8IvRjFf8XCARzZWxmCAn9AAABWcgU2aUUCRgBAhkEADbugBX9AU8wggFLMIIBAwYHKoZIzj0CATCB9wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEQQRrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQEDQgAES9Cb9iANUNYmwt5bjwNW1mZgjzIkDJb6FTCdiYWnkMMIVxh2YDllphoWDEAPS6kqJczzCuhnGYpZCp9tTaYKGxZMGwEDHB0HGwgDbmRuCAVzaXRlMQgDS0VZCAgRvCL0YxX/F/0A/Sb9AP4PMTk3MDAxMDFUMDAwMDAw/QD/DzIwMzcwMTE3VDIxMjg0NhdIMEYCIQDXkR1hF3GiP7yLXq+0JBJfi9QC+hhAu/1Bykx+MWz6RAIhANwelBTxxZr2C5bD15mjfhWudK4I1tOb4b/9xWCHyM7F" + "certificate": "Bv0BKwcrCANuZG4IBXNpdGUxCANLRVkICEKyYEYHiBwyCARzZWxmNggAAAF/V5V9QhQJGAECGQQANu6AFVswWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARRaZbFLRSnL1fmj8X3hInCCPy4qe17QujMMYq8qe+CKqV+OjexhrUvpwRDImRZOgXLCjOTyYnW3wxlxskTz8Y3FkwbAQMcHQcbCANuZG4IBXNpdGUxCANLRVkICEKyYEYHiBwy/QD9Jv0A/g8xOTcwMDEwMVQwMDAwMDD9AP8PMjA0MjAyMjhUMDA1ODA5F0YwRAIgFtFP0WocLQCtbwMTnqNtnCDmu62EJyC4uuCZ4Q/Wb8UCIGHb3e4St78378py81GjEZd/2L/aGbE3vbYQIiNxIYPN" } ] } \ No newline at end of file diff --git a/tests/unit-tests/configuration.t.cpp b/tests/unit-tests/configuration.t.cpp index f7a8bc5..bb380f9 100644 --- a/tests/unit-tests/configuration.t.cpp +++ b/tests/unit-tests/configuration.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -51,8 +51,8 @@ BOOST_AUTO_TEST_CASE(CaConfigFile) BOOST_CHECK_EQUAL(config.caProfile.supportedChallenges.front(), "pin"); config.load("tests/unit-tests/config-files/config-ca-5"); - BOOST_CHECK_EQUAL(config.redirection[0]->getName(), - "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5"); + BOOST_CHECK_EQUAL(config.redirection[0].first->getName(), + "/ndn/edu/ucla/KEY/m%08%98%C2xNZ%13/self/v=1646441513929"); BOOST_CHECK_EQUAL(config.nameAssignmentFuncs.size(), 3); BOOST_CHECK_EQUAL(config.nameAssignmentFuncs[0]->m_nameFormat[0], "group"); BOOST_CHECK_EQUAL(config.nameAssignmentFuncs[0]->m_nameFormat[1], "email"); @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(ProfileStorageConfigFile) BOOST_CHECK_EQUAL(profile1.probeParameterKeys.size(), 1); BOOST_CHECK_EQUAL(profile1.probeParameterKeys.front(), "email"); BOOST_CHECK_EQUAL(profile1.cert->getName(), - "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5"); + "/ndn/site1/KEY/B%B2%60F%07%88%1C2/self/v=1646441889090"); auto& profile2 = profileStorage.getKnownProfiles().back(); BOOST_CHECK_EQUAL(profile2.caPrefix, "/ndn/edu/ucla/zhiyi"); @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(ProfileStorageConfigFile) BOOST_CHECK(!profile2.maxSuffixLength); BOOST_CHECK_EQUAL(profile2.probeParameterKeys.size(), 0); BOOST_CHECK_EQUAL(profile2.cert->getName(), - "/ndn/site1/KEY/%11%BC%22%F4c%15%FF%17/self/%FD%00%00%01Y%C8%14%D9%A5"); + "/ndn/site1/KEY/B%B2%60F%07%88%1C2/self/v=1646441889090"); } BOOST_AUTO_TEST_CASE(ProfileStorageWithErrors) diff --git a/tests/unit-tests/name-assignment.t.cpp b/tests/unit-tests/name-assignment.t.cpp index 94b7fef..cecbc59 100644 --- a/tests/unit-tests/name-assignment.t.cpp +++ b/tests/unit-tests/name-assignment.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -18,6 +18,7 @@ * See AUTHORS.md for complete list of ndncert authors and contributors. */ +#include "name-assignment/assignment-email.hpp" #include "name-assignment/assignment-random.hpp" #include "name-assignment/assignment-param.hpp" #include "name-assignment/assignment-hash.hpp" @@ -49,6 +50,14 @@ BOOST_AUTO_TEST_CASE(NameAssignmentParam) BOOST_CHECK_EQUAL(*assignment.assignName(params).begin(), Name("/123/789")); params.find("xyz")->second = ""; BOOST_CHECK_EQUAL(assignment.assignName(params).size(), 0); + + AssignmentParam assignment2("/\"guest\"/email"); + params.emplace("email", "1@1.com"); + BOOST_CHECK_EQUAL(assignment2.assignName(params).size(), 1); + BOOST_CHECK_EQUAL(assignment2.assignName(params).begin()->toUri(), Name("/guest/1@1.com").toUri()); + + AssignmentParam assignment3("/\"/email"); + BOOST_CHECK_EQUAL(assignment3.assignName(params).size(), 0); } BOOST_AUTO_TEST_CASE(NameAssignmentHash) @@ -68,6 +77,20 @@ BOOST_AUTO_TEST_CASE(NameAssignmentHash) BOOST_CHECK_EQUAL(assignment.assignName(params).begin()->size(), 2); } +BOOST_AUTO_TEST_CASE(NameAssignmentEmail) +{ + AssignmentEmail assignment("/edu/ucla"); + std::multimap params; + BOOST_CHECK_EQUAL(assignment.assignName(params).size(), 0); + params.emplace("email", "das@math.ucla.edu"); + BOOST_CHECK_EQUAL(*assignment.assignName(params).begin(), Name("/math/das")); + + params.clear(); + params.emplace("email", "d/~.^as@6666=.9!"); + BOOST_CHECK_EQUAL(assignment.assignName(params).size(), 1); + BOOST_CHECK_EQUAL(*assignment.assignName(params).begin(), Name("/9!/6666%3D/d%2F~.%5Eas")); +} + BOOST_AUTO_TEST_SUITE_END() // TestNameAssignment } // namespace tests diff --git a/tests/unit-tests/protocol-encoders.t.cpp b/tests/unit-tests/protocol-encoders.t.cpp index bc1daa0..720c10e 100644 --- a/tests/unit-tests/protocol-encoders.t.cpp +++ b/tests/unit-tests/protocol-encoders.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -79,7 +79,9 @@ BOOST_AUTO_TEST_CASE(ProbeEncodingData) std::vector names; names.emplace_back("/ndn/1"); names.emplace_back("/ndn/2"); - auto b = probetlv::encodeDataContent(names, 2, config.redirection); + std::vector redirectionNames; + for (const auto& i : config.redirection) redirectionNames.push_back(i.first->getFullName()); + auto b = probetlv::encodeDataContent(names, 2, redirectionNames); std::vector> retNames; std::vector redirection; probetlv::decodeDataContent(b, retNames, redirection); @@ -94,7 +96,7 @@ BOOST_AUTO_TEST_CASE(ProbeEncodingData) auto it3 = redirection.begin(); auto it4 = config.redirection.begin(); for (; it3 != redirection.end() && it4 != config.redirection.end(); it3++, it4++) { - BOOST_CHECK_EQUAL(*it3, (*it4)->getFullName()); + BOOST_CHECK_EQUAL(*it3, it4->first->getFullName()); } } diff --git a/tests/unit-tests/redirection-policy.t.cpp b/tests/unit-tests/redirection-policy.t.cpp new file mode 100644 index 0000000..d8d5203 --- /dev/null +++ b/tests/unit-tests/redirection-policy.t.cpp @@ -0,0 +1,80 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017-2022, Regents of the University of California. + * + * This file is part of ndncert, a certificate management system based on NDN. + * + * ndncert 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. + * + * ndncert 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 copies of the GNU General Public License along with + * ndncert, e.g., in COPYING.md file. If not, see . + * + * See AUTHORS.md for complete list of ndncert authors and contributors. + */ + +#include "redirection/redirection-policy.hpp" +#include "redirection/redirection-param.hpp" +#include "redirection/redirection-email.hpp" +#include "test-common.hpp" + +namespace ndncert { +namespace tests { + +BOOST_AUTO_TEST_SUITE(TestRedirectionPolicy) + +BOOST_AUTO_TEST_CASE(RedirectionPolicyParam) +{ + RedirectionParam assignment(""); + std::multimap params; + BOOST_CHECK(assignment.isRedirecting(params)); + params.emplace("abc", "123"); + BOOST_CHECK(assignment.isRedirecting(params)); + + RedirectionParam assignment1("abc=123"); + params.clear(); + BOOST_CHECK(!assignment1.isRedirecting(params)); + params.emplace("abc", "124"); + BOOST_CHECK(!assignment1.isRedirecting(params)); + params.emplace("abc", "123"); + BOOST_CHECK(assignment1.isRedirecting(params)); + + RedirectionParam assignment2("abc=123&xyz=789"); + params.clear(); + BOOST_CHECK(!assignment2.isRedirecting(params)); + params.emplace("abc", "123"); + BOOST_CHECK(!assignment2.isRedirecting(params)); + params.emplace("xyz", "788"); + BOOST_CHECK(!assignment2.isRedirecting(params)); + params.emplace("xyz", "789"); + BOOST_CHECK(assignment2.isRedirecting(params)); + params.emplace("abz", "789"); + BOOST_CHECK(assignment2.isRedirecting(params)); +} + +BOOST_AUTO_TEST_CASE(RedirectionPolicyEmail) +{ + RedirectionEmail assignment("cs.ucla.edu"); + std::multimap params; + BOOST_CHECK(!assignment.isRedirecting(params)); + params.emplace("email", "das@math.ucla.edu"); + BOOST_CHECK(!assignment.isRedirecting(params)); + + params.clear(); + params.emplace("email", "das@cs.ucla.edu"); + BOOST_CHECK(assignment.isRedirecting(params)); + + params.clear(); + params.emplace("email", "das@ucla.edu"); + BOOST_CHECK(!assignment.isRedirecting(params)); +} + +BOOST_AUTO_TEST_SUITE_END() // TestNameAssignment + +} // namespace tests +} // namespace ndncert diff --git a/tests/unit-tests/requester.t.cpp b/tests/unit-tests/requester.t.cpp index d2833c4..73da390 100644 --- a/tests/unit-tests/requester.t.cpp +++ b/tests/unit-tests/requester.t.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -70,8 +70,8 @@ BOOST_AUTO_TEST_CASE(OnProbeResponse){ ca_profile.cert = std::make_shared(cert); std::vector availableNames; - availableNames.push_back(Name("/site1")); - availableNames.push_back(Name("/site2")); + availableNames.emplace_back("/site1"); + availableNames.emplace_back("/site2"); ndn::util::DummyClientFace face(io, m_keyChain, {true, true}); ca::CaModule ca(face, m_keyChain, "tests/unit-tests/config-files/config-ca-5", "ca-storage-memory"); @@ -79,7 +79,11 @@ BOOST_AUTO_TEST_CASE(OnProbeResponse){ Data reply; reply.setName(Name("/site/CA/PROBE")); reply.setFreshnessPeriod(time::seconds(100)); - reply.setContent(probetlv::encodeDataContent(availableNames, 3, ca.m_config.redirection)); + { + std::vector redirectionNames; + for (const auto &i : ca.m_config.redirection) redirectionNames.push_back(i.first->getFullName()); + reply.setContent(probetlv::encodeDataContent(availableNames, 3, redirectionNames)); + } m_keyChain.sign(reply, ndn::signingByIdentity(identity)); std::vector> names; @@ -94,8 +98,8 @@ BOOST_AUTO_TEST_CASE(OnProbeResponse){ BOOST_CHECK_EQUAL(names[1].second, 3); BOOST_CHECK_EQUAL(redirects.size(), 2); - BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirects[0].getPrefix(-1)), "/ndn/site1"); - BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirects[1].getPrefix(-1)), "/ndn/site1"); + BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirects[0].getPrefix(-1)), "/ndn/edu/ucla"); + BOOST_CHECK_EQUAL(ndn::security::extractIdentityFromCertName(redirects[1].getPrefix(-1)), "/ndn/edu/ucla/cs/irl"); } BOOST_AUTO_TEST_CASE(ErrorHandling) diff --git a/tools/ndncert-ca-server.cpp b/tools/ndncert-ca-server.cpp index 5f0e3a3..8260502 100644 --- a/tools/ndncert-ca-server.cpp +++ b/tools/ndncert-ca-server.cpp @@ -1,6 +1,6 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2017-2021, Regents of the University of California. + * Copyright (c) 2017-2022, Regents of the University of California. * * This file is part of ndncert, a certificate management system based on NDN. * @@ -155,9 +155,6 @@ main(int argc, char* argv[]) return; } } - }, - [](const Name&, const std::string& errorInfo) { - std::cerr << "ERROR: " << errorInfo << std::endl; }); }