blob: 46f04ea15039945295d58dd2c8dfc274449b9560 [file] [log] [blame]
Yingdi Yu77627ab2015-07-21 16:13:49 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yingdi Yu0a312e52015-07-22 13:14:53 -07003 * Copyright (c) 2014-2015, Regents of the University of California.
Yingdi Yu77627ab2015-07-21 16:13:49 -07004 *
Yingdi Yu0a312e52015-07-22 13:14:53 -07005 * This file is part of ndn-tools (Named Data Networking Essential Tools).
6 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
Yingdi Yu77627ab2015-07-21 16:13:49 -07007 *
Yingdi Yu0a312e52015-07-22 13:14:53 -07008 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Yingdi Yu77627ab2015-07-21 16:13:49 -070011 *
Yingdi Yu0a312e52015-07-22 13:14:53 -070012 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Yingdi Yu77627ab2015-07-21 16:13:49 -070015 *
Yingdi Yu0a312e52015-07-22 13:14:53 -070016 * You should have received a copy of the GNU General Public License along with
17 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Yingdi Yu77627ab2015-07-21 16:13:49 -070018 *
Yingdi Yu0a312e52015-07-22 13:14:53 -070019 * @author Yingdi Yu <yingdi@cs.ucla.edu>
Yingdi Yu77627ab2015-07-21 16:13:49 -070020 */
21
22#include "delete-query-processor.hpp"
23#include "encoding/pib-encoding.hpp"
24#include "pib.hpp"
25
26#include <boost/lexical_cast.hpp>
27
28namespace ndn {
29namespace pib {
30
31using std::string;
32
33const size_t DeleteQueryProcessor::DELETE_QUERY_LENGTH = 9;
34const Name DeleteQueryProcessor::PIB_PREFIX("/localhost/pib");
35
36DeleteQueryProcessor::DeleteQueryProcessor(PibDb& db)
37 : m_db(db)
38{
39}
40
41std::pair<bool, Block>
42DeleteQueryProcessor::operator()(const Interest& interest)
43{
44 const Name& interestName = interest.getName();
45
46 // handle pib query: /localhost/pib/[UserName]/delete/param/<signed_interest_related_components>
47 if (interestName.size() != DELETE_QUERY_LENGTH) {
48 // malformed interest, discard
49 return std::make_pair(false, Block());
50 }
51
52 try {
53 DeleteParam param;
54 param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
55
56 SignatureInfo sigInfo;
57 sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
58
59 // sigInfo must have KeyLocator.Name if the interest passed validation.
60 Name signerName;
61 signerName = sigInfo.getKeyLocator().getName();
62
63 switch (param.getTargetType()) {
64 case TYPE_USER:
65 return std::make_pair(true, PibError(ERR_WRONG_PARAM, "not allowed to delete user").wireEncode());
66 case TYPE_ID:
67 return processDeleteIdQuery(param, signerName);
68 case TYPE_KEY:
69 return processDeleteKeyQuery(param, signerName);
70 case TYPE_CERT:
71 return processDeleteCertQuery(param, signerName);
72 default:
73 {
74 PibError error(ERR_WRONG_PARAM,
75 "target type is not supported: " +
76 boost::lexical_cast<string>(param.getTargetType()));
77 return std::make_pair(true, error.wireEncode());
78 }
79 }
80 }
81 catch (const PibDb::Error& e) {
82 PibError error(ERR_INTERNAL_ERROR, e.what());
83 return std::make_pair(true, error.wireEncode());
84 }
85 catch (const tlv::Error& e) {
86 PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
87 return std::make_pair(true, error.wireEncode());
88 }
89}
90
91std::pair<bool, Block>
92DeleteQueryProcessor::processDeleteIdQuery(const DeleteParam& param, const Name& signerName)
93{
94 Name identity = param.getTargetName();
95 if (!isDeleteAllowed(TYPE_ID, identity, signerName)) {
96 PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
97 return std::make_pair(true, error.wireEncode());
98 }
99
100 m_db.deleteIdentity(identity);
101
102 return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
103}
104
105std::pair<bool, Block>
106DeleteQueryProcessor::processDeleteKeyQuery(const DeleteParam& param, const Name& signerName)
107{
108 const Name& keyName = param.getTargetName();
109 if (!isDeleteAllowed(TYPE_KEY, keyName, signerName)) {
110 PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
111 return std::make_pair(true, error.wireEncode());
112 }
113
114 m_db.deleteKey(keyName);
115
116 return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
117}
118
119std::pair<bool, Block>
120DeleteQueryProcessor::processDeleteCertQuery(const DeleteParam& param, const Name& signerName)
121{
122 const Name& certName = param.getTargetName();
123 if (!isDeleteAllowed(TYPE_CERT, certName, signerName)) {
124 PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
125 return std::make_pair(true, error.wireEncode());
126 }
127
128 m_db.deleteCertificate(certName);
129
130 return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
131}
132
133bool
134DeleteQueryProcessor::isDeleteAllowed(const pib::Type targetType,
135 const Name& targetName,
136 const Name& signer) const
137{
138 // sanity checking, user cannot be deleted.
139 if (targetType == TYPE_USER)
140 return false;
141
142 // Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
143 // that prefix will be rejected.
144 if (PIB_PREFIX.isPrefixOf(targetName))
145 return false;
146
147 // Rules for other items:
148 //
149 // signer | deleting privilege
150 // =========================+===============================================
151 // local mgmt key | any id, key, and cert
152 // -------------------------+-----------------------------------------------
153 // default key of an id | any id, key, and cert under the id's namespace
154 // -------------------------+-----------------------------------------------
155 // non-default key of an id | any cert of the key
156
157 const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
158 const Name& signerId = signerKeyName.getPrefix(-1);
159
160 bool hasSignerDefaultKey = true;
161 Name signerDefaultKeyName;
162 try {
163 signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
164 }
165 catch (PibDb::Error&) {
166 hasSignerDefaultKey = false;
167 }
168
169 Name mgmtCertName;
170 try {
171 mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
172 }
173 catch (PibDb::Error&) {
174 return false;
175 }
176
177 if (signer == mgmtCertName) {
178 // signer is current management key, anything is allowed.
179 return true;
180 }
181 else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
182 // signer is an identity's default key
183 if (!signerId.isPrefixOf(targetName))
184 return false;
185 else
186 return true;
187 }
188 else {
189 // non-default key
190 if (targetType == TYPE_CERT) {
191 // check if it is for the key's cert
192 if (IdentityCertificate::certificateNameToPublicKeyName(targetName) == signerKeyName)
193 return true;
194 }
195 else if (targetType == TYPE_KEY) {
196 // check if it is for the key itself
197 if (targetName == signerKeyName)
198 return true;
199 }
200 return false;
201 }
202}
203
204} // namespace pib
205} // namespace ndn