blob: 69c2d4bb1e41b362d37b71cecc4b3d6110381915 [file] [log] [blame]
Yingdi Yu9236c432013-10-18 11:29:25 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
Yingdi Yuf8f572d2014-01-13 11:19:47 -080011#if __clang__
Yingdi Yuf8f572d2014-01-13 11:19:47 -080012#pragma clang diagnostic ignored "-Wtautological-compare"
Yingdi Yuf8f572d2014-01-13 11:19:47 -080013#endif
14
Yingdi Yu0b0a7362014-08-05 16:31:30 -070015#include "contact-manager.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080016#include <QStringList>
Yingdi Yu06f572b2014-03-11 15:46:10 -070017#include <QFile>
Yingdi Yu9236c432013-10-18 11:29:25 -070018
Yingdi Yu4685b1b2013-10-18 17:05:02 -070019#ifndef Q_MOC_RUN
Yingdi Yufa0b6a02014-04-30 14:26:42 -070020#include <ndn-cxx/util/crypto.hpp>
21#include <ndn-cxx/util/io.hpp>
22#include <ndn-cxx/security/sec-rule-relative.hpp>
23#include <ndn-cxx/security/validator-regex.hpp>
Yingdi Yu0b0a7362014-08-05 16:31:30 -070024#include "cryptopp.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080025#include <boost/asio.hpp>
26#include <boost/tokenizer.hpp>
27#include <boost/filesystem.hpp>
Yingdi Yuec3d9a32013-10-18 18:35:09 -070028#include "logging.h"
Yingdi Yu4685b1b2013-10-18 17:05:02 -070029#endif
Yingdi Yu9236c432013-10-18 11:29:25 -070030
Yingdi Yu348f5ea2014-03-01 14:47:25 -080031namespace fs = boost::filesystem;
Yingdi Yu9236c432013-10-18 11:29:25 -070032
Yingdi Yu0b0a7362014-08-05 16:31:30 -070033// INIT_LOGGER("chronos.ContactManager");
Yingdi Yuec3d9a32013-10-18 18:35:09 -070034
Yingdi Yufa4ce792014-02-06 18:09:22 -080035namespace chronos{
Yingdi Yu4685b1b2013-10-18 17:05:02 -070036
Yingdi Yu0b0a7362014-08-05 16:31:30 -070037using std::string;
38using std::map;
39using std::vector;
40
41using ndn::Face;
42using ndn::OBufferStream;
43using ndn::IdentityCertificate;
44using ndn::Validator;
45using ndn::ValidatorRegex;
46using ndn::SecRuleRelative;
47using ndn::OnDataValidated;
48using ndn::OnDataValidationFailed;
49using ndn::OnInterestValidated;
50using ndn::OnInterestValidationFailed;
Yingdi Yu17032f82014-03-25 15:48:23 -070051
Yingdi Yu348f5ea2014-03-01 14:47:25 -080052
Yingdi Yu2c9e7712014-10-20 11:55:05 -070053ContactManager::ContactManager(Face& face,
Yingdi Yufa4ce792014-02-06 18:09:22 -080054 QObject* parent)
55 : QObject(parent)
Yingdi Yufa4ce792014-02-06 18:09:22 -080056 , m_face(face)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080057 , m_dnsListenerId(0)
Yingdi Yufa4ce792014-02-06 18:09:22 -080058{
Yingdi Yu76dd8002013-12-24 11:16:32 +080059 initializeSecurity();
Yingdi Yu9236c432013-10-18 11:29:25 -070060}
61
62ContactManager::~ContactManager()
Yingdi Yu0b0a7362014-08-05 16:31:30 -070063{
64}
Yingdi Yu9236c432013-10-18 11:29:25 -070065
Yingdi Yu348f5ea2014-03-01 14:47:25 -080066// private methods
Yingdi Yu06f572b2014-03-11 15:46:10 -070067shared_ptr<IdentityCertificate>
68ContactManager::loadTrustAnchor()
69{
70 shared_ptr<IdentityCertificate> anchor;
71
72 QFile anchorFile(":/security/anchor.cert");
73
Yingdi Yu0b0a7362014-08-05 16:31:30 -070074 if (!anchorFile.open(QIODevice::ReadOnly)) {
75 emit warning(QString("Cannot load trust anchor!"));
76 return anchor;
77 }
Yingdi Yu06f572b2014-03-11 15:46:10 -070078
79 qint64 fileSize = anchorFile.size();
80 char* buf = new char[fileSize];
81 anchorFile.read(buf, fileSize);
82
Yingdi Yu0b0a7362014-08-05 16:31:30 -070083 try {
84 using namespace CryptoPP;
Yingdi Yu06f572b2014-03-11 15:46:10 -070085
Yingdi Yu0b0a7362014-08-05 16:31:30 -070086 OBufferStream os;
87 StringSource(reinterpret_cast<const uint8_t*>(buf), fileSize, true,
88 new Base64Decoder(new FileSink(os)));
89 anchor = make_shared<IdentityCertificate>();
90 anchor->wireDecode(Block(os.buf()));
91 }
92 catch (CryptoPP::Exception& e) {
93 emit warning(QString("Cannot load trust anchor!"));
94 }
95 catch (IdentityCertificate::Error& e) {
96 emit warning(QString("Cannot load trust anchor!"));
97 }
98 catch(Block::Error& e) {
99 emit warning(QString("Cannot load trust anchor!"));
100 }
Yingdi Yu06f572b2014-03-11 15:46:10 -0700101
102 delete [] buf;
103
104 return anchor;
105}
106
Yingdi Yu76dd8002013-12-24 11:16:32 +0800107void
108ContactManager::initializeSecurity()
109{
Yingdi Yu06f572b2014-03-11 15:46:10 -0700110 shared_ptr<IdentityCertificate> anchor = loadTrustAnchor();
Yingdi Yufa4ce792014-02-06 18:09:22 -0800111
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700112 shared_ptr<ValidatorRegex> validator = make_shared<ValidatorRegex>(boost::ref(m_face));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800113 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><ENDORSED>",
114 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
115 "==", "\\1", "\\1\\2", true));
116 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><><ENDORSEE>",
117 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
118 "==", "\\1", "\\1\\2", true));
119 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><PROFILE>",
120 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
121 "==", "\\1", "\\1\\2", true));
122 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<PROFILE-CERT>]*)<PROFILE-CERT>",
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700123 "^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$",
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800124 "==", "\\1", "\\1\\2", true));
125 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
126 "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>$",
127 ">", "\\1\\2", "\\1", true));
128 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
129 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
130 "==", "\\1", "\\1\\2", true));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700131 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^(<>*)$",
132 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800133 ">", "\\1", "\\1\\2", true));
134 validator->addTrustAnchor(anchor);
135 m_validator = validator;
Yingdi Yu76dd8002013-12-24 11:16:32 +0800136}
137
138void
Yingdi Yufa4ce792014-02-06 18:09:22 -0800139ContactManager::fetchCollectEndorse(const Name& identity)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800140{
141 Name interestName = identity;
142 interestName.append("DNS").append("ENDORSED");
143
Yingdi Yu76dd8002013-12-24 11:16:32 +0800144 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700145 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800146 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800147
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700148 OnDataValidated onValidated =
149 bind(&ContactManager::onDnsCollectEndorseValidated, this, _1, identity);
150 OnDataValidationFailed onValidationFailed =
151 bind(&ContactManager::onDnsCollectEndorseValidationFailed, this, _1, _2, identity);
152 TimeoutNotify timeoutNotify =
153 bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, _1, identity);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800154
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800155 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800156}
157
158void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800159ContactManager::fetchEndorseCertificateInternal(const Name& identity, int certIndex)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800160{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700161 shared_ptr<EndorseCollection> endorseCollection =
162 m_bufferedContacts[identity].m_endorseCollection;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800163
164 if(certIndex >= endorseCollection->endorsement_size())
165 prepareEndorseInfo(identity);
166
167 Name interestName(endorseCollection->endorsement(certIndex).certname());
168
Yingdi Yu76dd8002013-12-24 11:16:32 +0800169 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700170 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800171 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800172
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700173 m_face.expressInterest(interest,
174 bind(&ContactManager::onEndorseCertificateInternal,
175 this, _1, _2, identity, certIndex,
176 endorseCollection->endorsement(certIndex).hash()),
177 bind(&ContactManager::onEndorseCertificateInternalTimeout,
178 this, _1, identity, certIndex));
Yingdi Yu76dd8002013-12-24 11:16:32 +0800179}
180
Yingdi Yu76dd8002013-12-24 11:16:32 +0800181void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800182ContactManager::prepareEndorseInfo(const Name& identity)
Yingdi Yu76dd8002013-12-24 11:16:32 +0800183{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800184 // _LOG_DEBUG("prepareEndorseInfo");
185 const Profile& profile = m_bufferedContacts[identity].m_selfEndorseCert->getProfile();
Yingdi Yu76dd8002013-12-24 11:16:32 +0800186
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700187 shared_ptr<Chronos::EndorseInfo> endorseInfo = make_shared<Chronos::EndorseInfo>();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800188 m_bufferedContacts[identity].m_endorseInfo = endorseInfo;
189
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700190 map<string, int> endorseCount;
191 for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
192 // _LOG_DEBUG("prepareEndorseInfo: profile[" << pIt->first << "]: " << pIt->second);
193 endorseCount[pIt->first] = 0;
194 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800195
196 int endorseCertCount = 0;
197
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700198 vector<shared_ptr<EndorseCertificate> >::const_iterator cIt =
199 m_bufferedContacts[identity].m_endorseCertList.begin();
200 vector<shared_ptr<EndorseCertificate> >::const_iterator cEnd =
201 m_bufferedContacts[identity].m_endorseCertList.end();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800202
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700203 for (; cIt != cEnd; cIt++, endorseCertCount++) {
204 shared_ptr<Contact> contact = getContact((*cIt)->getSigner().getPrefix(-1));
205 if (!static_cast<bool>(contact))
206 continue;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700207
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700208 if (!contact->isIntroducer() ||
209 !contact->canBeTrustedFor(profile.getIdentityName()))
210 continue;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800211
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700212 if (!Validator::verifySignature(**cIt, contact->getPublicKey()))
213 continue;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800214
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700215 const Profile& tmpProfile = (*cIt)->getProfile();
216 if (tmpProfile != profile)
217 continue;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800218
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700219 const vector<string>& endorseList = (*cIt)->getEndorseList();
220 for (vector<string>::const_iterator eIt = endorseList.begin(); eIt != endorseList.end(); eIt++)
221 endorseCount[*eIt] += 1;
222 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800223
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700224 for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
225 Chronos::EndorseInfo::Endorsement* endorsement = endorseInfo->add_endorsement();
226 endorsement->set_type(pIt->first);
227 endorsement->set_value(pIt->second);
228 std::stringstream ss;
229 ss << endorseCount[pIt->first] << "/" << endorseCertCount;
230 endorsement->set_endorse(ss.str());
231 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800232
233 emit contactEndorseInfoReady (*endorseInfo);
234}
235
236void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700237ContactManager::onDnsSelfEndorseCertValidated(const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800238 const Name& identity)
239{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700240 try {
241 Data plainData;
242 plainData.wireDecode(data->getContent().blockFromValue());
243 shared_ptr<EndorseCertificate> selfEndorseCertificate =
244 make_shared<EndorseCertificate>(boost::cref(plainData));
245 if (Validator::verifySignature(plainData, selfEndorseCertificate->getPublicKeyInfo())) {
246 m_bufferedContacts[identity].m_selfEndorseCert = selfEndorseCertificate;
247 fetchCollectEndorse(identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800248 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700249 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800250 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700251 }
252 catch(Block::Error& e) {
253 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
254 }
255 catch(Data::Error& e) {
256 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
257 }
258 catch(EndorseCertificate::Error& e) {
259 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
260 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800261}
262
263void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700264ContactManager::onDnsSelfEndorseCertValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700265 const string& failInfo,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800266 const Name& identity)
267{
268 // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
269 // but let's stay with failure for now.
270 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
271}
272
273void
274ContactManager::onDnsSelfEndorseCertTimeoutNotify(const Interest& interest,
275 const Name& identity)
276{
277 // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
278 // but let's stay with failure for now.
279 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
280}
281
282void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700283ContactManager::onDnsCollectEndorseValidated(const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800284 const Name& identity)
285{
286 shared_ptr<EndorseCollection> endorseCollection = make_shared<EndorseCollection>();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700287 if (!endorseCollection->ParseFromArray(data->getContent().value(),
288 data->getContent().value_size())) {
289 m_bufferedContacts[identity].m_endorseCollection = endorseCollection;
290 fetchEndorseCertificateInternal(identity, 0);
291 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800292 else
293 prepareEndorseInfo(identity);
294}
295
296void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700297ContactManager::onDnsCollectEndorseValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700298 const string& failInfo,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800299 const Name& identity)
300{
301 prepareEndorseInfo(identity);
302}
303
304void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700305ContactManager::onDnsCollectEndorseTimeoutNotify(const Interest& interest, const Name& identity)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800306{
307 // _LOG_DEBUG("onDnsCollectEndorseTimeoutNotify: " << interest.getName());
308 prepareEndorseInfo(identity);
309}
310
311void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700312ContactManager::onEndorseCertificateInternal(const Interest& interest, Data& data,
313 const Name& identity, int certIndex, string hash)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800314{
Yingdi Yu17032f82014-03-25 15:48:23 -0700315 std::stringstream ss;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700316 {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800317 using namespace CryptoPP;
318
319 SHA256 hash;
320 StringSource(data.wireEncode().wire(), data.wireEncode().size(), true,
321 new HashFilter(hash, new FileSink(ss)));
322 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700323
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700324 if (ss.str() == hash) {
325 shared_ptr<EndorseCertificate> endorseCertificate =
326 make_shared<EndorseCertificate>(boost::cref(data));
327 m_bufferedContacts[identity].m_endorseCertList.push_back(endorseCertificate);
328 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800329
330 fetchEndorseCertificateInternal(identity, certIndex+1);
331}
332
333void
334ContactManager::onEndorseCertificateInternalTimeout(const Interest& interest,
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700335 const Name& identity,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800336 int certIndex)
337{
338 fetchEndorseCertificateInternal(identity, certIndex+1);
339}
340
341void
342ContactManager::collectEndorsement()
343{
344 {
345 boost::recursive_mutex::scoped_lock lock(m_collectCountMutex);
346 m_collectCount = m_contactList.size();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700347
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700348 for (ContactList::iterator it = m_contactList.begin(); it != m_contactList.end(); it++) {
349 Name interestName = (*it)->getNameSpace();
350 interestName.append("DNS").append(m_identity.wireEncode()).append("ENDORSEE");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800351
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700352 Interest interest(interestName);
353 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700354
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700355 OnDataValidated onValidated = bind(&ContactManager::onDnsEndorseeValidated, this, _1);
356 OnDataValidationFailed onValidationFailed =
357 bind(&ContactManager::onDnsEndorseeValidationFailed, this, _1, _2);
358 TimeoutNotify timeoutNotify = bind(&ContactManager::onDnsEndorseeTimeoutNotify, this, _1);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700359
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700360 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
361 }
Yingdi Yu76dd8002013-12-24 11:16:32 +0800362 }
363}
364
365void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800366ContactManager::onDnsEndorseeValidated(const shared_ptr<const Data>& data)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800367{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800368 Data endorseData;
369 endorseData.wireDecode(data->getContent().blockFromValue());
Yingdi Yu76dd8002013-12-24 11:16:32 +0800370
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800371 EndorseCertificate endorseCertificate(endorseData);
372 m_contactStorage->updateCollectEndorse(endorseCertificate);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800373
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800374 decreaseCollectStatus();
Yingdi Yu76dd8002013-12-24 11:16:32 +0800375}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800376
377void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700378ContactManager::onDnsEndorseeValidationFailed(const shared_ptr<const Data>& data,
379 const string& failInfo)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700380{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800381 decreaseCollectStatus();
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700382}
383
Yingdi Yub2e747d2013-11-05 23:06:43 -0800384void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800385ContactManager::onDnsEndorseeTimeoutNotify(const Interest& interest)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800386{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800387 decreaseCollectStatus();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800388}
389
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700390void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800391ContactManager::decreaseCollectStatus()
Yingdi Yub2e747d2013-11-05 23:06:43 -0800392{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700393 int count;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800394 {
395 boost::recursive_mutex::scoped_lock lock(m_collectCountMutex);
396 m_collectCount--;
397 count = m_collectCount;
398 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800399
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800400 if(count == 0)
401 publishCollectEndorsedDataInDNS();
402}
Yingdi Yub2e747d2013-11-05 23:06:43 -0800403
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800404void
405ContactManager::publishCollectEndorsedDataInDNS()
406{
407 Name dnsName = m_identity;
408 dnsName.append("DNS").append("ENDORSED").appendVersion();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800409
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700410 shared_ptr<Data> data = make_shared<Data>();
411 data->setName(dnsName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800412
413 EndorseCollection endorseCollection;
414 m_contactStorage->getCollectEndorse(endorseCollection);
415
416 OBufferStream os;
417 endorseCollection.SerializeToOstream(&os);
418
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700419 data->setContent(os.buf());
420 m_keyChain.signByIdentity(*data, m_identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800421
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700422 m_contactStorage->updateDnsOthersEndorse(*data);
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700423 m_face.put(*data);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800424}
425
426void
427ContactManager::onIdentityCertValidated(const shared_ptr<const Data>& data)
428{
429 shared_ptr<IdentityCertificate> cert = make_shared<IdentityCertificate>(boost::cref(*data));
430 m_bufferedIdCerts[cert->getName()] = cert;
431 decreaseIdCertCount();
432}
433
434void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700435ContactManager::onIdentityCertValidationFailed(const shared_ptr<const Data>& data,
436 const string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800437{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700438 // _LOG_DEBUG("ContactManager::onIdentityCertValidationFailed " << data->getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800439 decreaseIdCertCount();
440}
441
442void
443ContactManager::onIdentityCertTimeoutNotify(const Interest& interest)
444{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700445 // _LOG_DEBUG("ContactManager::onIdentityCertTimeoutNotify: " << interest.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800446 decreaseIdCertCount();
447}
448
449void
450ContactManager::decreaseIdCertCount()
451{
452 int count;
453 {
454 boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
455 m_idCertCount--;
456 count = m_idCertCount;
457 }
458
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700459 if (count == 0) {
460 QStringList certNameList;
461 QStringList nameList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800462
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700463 for(BufferedIdCerts::const_iterator it = m_bufferedIdCerts.begin();
464 it != m_bufferedIdCerts.end(); it++) {
465 certNameList << QString::fromStdString(it->second->getName().toUri());
466 Profile profile(*(it->second));
467 nameList << QString::fromStdString(profile.get("name"));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800468 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700469
470 emit idCertNameListReady(certNameList);
471 emit nameListReady(nameList);
472 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800473}
474
Yingdi Yu76dd8002013-12-24 11:16:32 +0800475shared_ptr<EndorseCertificate>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800476ContactManager::getSignedSelfEndorseCertificate(const Profile& profile)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700477{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800478 Name certificateName = m_keyChain.getDefaultCertificateNameForIdentity(m_identity);
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700479
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800480 shared_ptr<IdentityCertificate> signingCert = m_keyChain.getCertificate(certificateName);
Yingdi Yu72781e52013-11-06 23:00:21 -0800481
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700482 vector<string> endorseList;
483 for (Profile::const_iterator it = profile.begin(); it != profile.end(); it++)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700484 endorseList.push_back(it->first);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700485
486 shared_ptr<EndorseCertificate> selfEndorseCertificate =
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700487 make_shared<EndorseCertificate>(boost::cref(*signingCert),
488 boost::cref(profile),
489 boost::cref(endorseList));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700490
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800491 m_keyChain.sign(*selfEndorseCertificate, certificateName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700492
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800493 return selfEndorseCertificate;
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700494}
495
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700496void
Yingdi Yu76dd8002013-12-24 11:16:32 +0800497ContactManager::publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700498{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800499 Name dnsName = m_identity;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800500 dnsName.append("DNS").append("PROFILE").appendVersion();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800501
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700502 shared_ptr<Data> data = make_shared<Data>();
503 data->setName(dnsName);
504 data->setContent(selfEndorseCertificate.wireEncode());
505 data->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu76dd8002013-12-24 11:16:32 +0800506
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700507 m_keyChain.signByIdentity(*data, m_identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800508
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700509 m_contactStorage->updateDnsSelfProfileData(*data);
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700510 m_face.put(*data);
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700511}
512
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700513shared_ptr<EndorseCertificate>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800514ContactManager::generateEndorseCertificate(const Name& identity)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800515{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800516 shared_ptr<Contact> contact = getContact(identity);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700517 if (!static_cast<bool>(contact))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800518 return shared_ptr<EndorseCertificate>();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800519
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800520 Name signerKeyName = m_keyChain.getDefaultKeyNameForIdentity(m_identity);
521
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700522 vector<string> endorseList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800523 m_contactStorage->getEndorseList(identity, endorseList);
524
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700525 shared_ptr<EndorseCertificate> cert =
526 shared_ptr<EndorseCertificate>(new EndorseCertificate(contact->getPublicKeyName(),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800527 contact->getPublicKey(),
528 contact->getNotBefore(),
529 contact->getNotAfter(),
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700530 signerKeyName,
531 contact->getProfile(),
532 endorseList));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800533 m_keyChain.signByIdentity(*cert, m_identity);
534 return cert;
535
536}
537
538void
539ContactManager::publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate)
540{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800541 Name endorsee = endorseCertificate.getPublicKeyName().getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800542 Name dnsName = m_identity;
543 dnsName.append("DNS")
544 .append(endorsee.wireEncode())
545 .append("ENDORSEE")
546 .appendVersion();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800547
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700548 shared_ptr<Data> data = make_shared<Data>();
549 data->setName(dnsName);
550 data->setContent(endorseCertificate.wireEncode());
Yingdi Yub2e747d2013-11-05 23:06:43 -0800551
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700552 m_keyChain.signByIdentity(*data, m_identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800553
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700554 m_contactStorage->updateDnsEndorseOthers(*data, dnsName.get(-3).toUri());
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700555 m_face.put(*data);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800556}
557
558void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800559ContactManager::sendInterest(const Interest& interest,
560 const OnDataValidated& onValidated,
561 const OnDataValidationFailed& onValidationFailed,
562 const TimeoutNotify& timeoutNotify,
563 int retry /* = 1 */)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800564{
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700565 m_face.expressInterest(interest,
566 bind(&ContactManager::onTargetData,
567 this, _1, _2, onValidated, onValidationFailed),
568 bind(&ContactManager::onTargetTimeout,
569 this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800570}
Yingdi Yu76dd8002013-12-24 11:16:32 +0800571
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800572void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700573ContactManager::onTargetData(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800574 const Data& data,
575 const OnDataValidated& onValidated,
576 const OnDataValidationFailed& onValidationFailed)
577{
578 // _LOG_DEBUG("On receiving data: " << data.getName());
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700579 m_validator->validate(data, onValidated, onValidationFailed);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800580}
Yingdi Yub2e747d2013-11-05 23:06:43 -0800581
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800582void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700583ContactManager::onTargetTimeout(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800584 int retry,
585 const OnDataValidated& onValidated,
586 const OnDataValidationFailed& onValidationFailed,
587 const TimeoutNotify& timeoutNotify)
588{
589 // _LOG_DEBUG("On interest timeout: " << interest.getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700590 if (retry > 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800591 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, retry-1);
592 else
593 timeoutNotify(interest);
594}
595
596void
597ContactManager::onDnsInterest(const Name& prefix, const Interest& interest)
598{
599 const Name& interestName = interest.getName();
600 shared_ptr<Data> data;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700601
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700602 if (interestName.size() <= prefix.size())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800603 return;
604
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700605 if (interestName.size() == (prefix.size()+1)) {
606 data = m_contactStorage->getDnsData("N/A", interestName.get(prefix.size()).toUri());
607 if (static_cast<bool>(data))
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700608 m_face.put(*data);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700609 return;
610 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800611
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700612 if (interestName.size() == (prefix.size()+2)) {
613 data = m_contactStorage->getDnsData(interestName.get(prefix.size()).toUri(),
614 interestName.get(prefix.size()+1).toUri());
615 if (static_cast<bool>(data))
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700616 m_face.put(*data);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700617 return;
618 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800619}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700620
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800621void
Yingdi Yu17032f82014-03-25 15:48:23 -0700622ContactManager::onDnsRegisterFailed(const Name& prefix, const std::string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800623{
624 emit warning(QString(failInfo.c_str()));
625}
626
627
628// public slots
629void
630ContactManager::onIdentityUpdated(const QString& identity)
631{
632 m_identity = Name(identity.toStdString());
633
634 m_contactStorage = make_shared<ContactStorage>(m_identity);
635
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800636 Name dnsPrefix;
637 dnsPrefix.append(m_identity).append("DNS");
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700638 const ndn::RegisteredPrefixId* dnsListenerId =
639 m_face.setInterestFilter(dnsPrefix,
640 bind(&ContactManager::onDnsInterest,
641 this, _1, _2),
642 bind(&ContactManager::onDnsRegisterFailed,
643 this, _1, _2));
644
645 if (m_dnsListenerId != 0)
646 m_face.unsetInterestFilter(m_dnsListenerId);
647
648 m_dnsListenerId = dnsListenerId;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800649
650 m_contactList.clear();
651 m_contactStorage->getAllContacts(m_contactList);
652
653 m_bufferedContacts.clear();
654
655 collectEndorsement();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800656}
657
Yingdi Yuae8217c2013-11-09 00:03:26 -0800658void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800659ContactManager::onFetchContactInfo(const QString& identity)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800660{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800661 // try to fetch self-endorse-certificate via DNS PROFILE first.
662 Name identityName(identity.toStdString());
663 Name interestName;
664 interestName.append(identityName).append("DNS").append("PROFILE");
Yingdi Yu76dd8002013-12-24 11:16:32 +0800665
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800666 // _LOG_DEBUG("onFetchContactInfo " << identity.toStdString() << " profile: " << interestName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700667
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800668 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700669 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800670 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800671
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700672 OnDataValidated onValidated =
673 bind(&ContactManager::onDnsSelfEndorseCertValidated, this, _1, identityName);
674 OnDataValidationFailed onValidationFailed =
675 bind(&ContactManager::onDnsSelfEndorseCertValidationFailed, this, _1, _2, identityName);
676 TimeoutNotify timeoutNotify =
677 bind(&ContactManager::onDnsSelfEndorseCertTimeoutNotify, this, _1, identityName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800678
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800679 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
680}
Yingdi Yu76dd8002013-12-24 11:16:32 +0800681
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800682void
683ContactManager::onAddFetchedContact(const QString& identity)
684{
685 // _LOG_DEBUG("onAddFetchedContact");
686
687 Name identityName(identity.toStdString());
688
689 BufferedContacts::const_iterator it = m_bufferedContacts.find(identityName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700690 if (it != m_bufferedContacts.end()) {
691 Contact contact(*(it->second.m_selfEndorseCert));
692 // _LOG_DEBUG("onAddFetchedContact: contact ready");
693 try {
694 m_contactStorage->addContact(contact);
695 m_bufferedContacts.erase(identityName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800696
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700697 m_contactList.clear();
698 m_contactStorage->getAllContacts(m_contactList);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800699
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700700 onWaitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800701 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700702 catch(ContactStorage::Error& e) {
703 emit warning(QString::fromStdString(e.what()));
704 }
705 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800706 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700707 emit warning(QString("Failure: no information of %1").arg(identity));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800708}
709
710void
711ContactManager::onUpdateProfile()
712{
713 // Get current profile;
714 shared_ptr<Profile> newProfile = m_contactStorage->getSelfProfile();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700715 if (!static_cast<bool>(newProfile))
Yingdi Yuae8217c2013-11-09 00:03:26 -0800716 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800717
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700718 // _LOG_DEBUG("ContactManager::onUpdateProfile: getProfile");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800719
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700720 shared_ptr<EndorseCertificate> newEndorseCertificate =
721 getSignedSelfEndorseCertificate(*newProfile);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800722
723 m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate);
724
725 publishSelfEndorseCertificateInDNS(*newEndorseCertificate);
726}
727
728void
729ContactManager::onRefreshBrowseContact()
730{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700731 vector<string> bufferedIdCertNames;
732 try {
733 using namespace boost::asio::ip;
734 tcp::iostream request_stream;
735 request_stream.expires_from_now(boost::posix_time::milliseconds(5000));
736 request_stream.connect("ndncert.named-data.net","80");
737 if (!request_stream) {
738 emit warning(QString::fromStdString("Fail to fetch certificate directory! #1"));
739 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800740 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700741
742 request_stream << "GET /cert/list/ HTTP/1.0\r\n";
743 request_stream << "Host: ndncert.named-data.net\r\n\r\n";
744 request_stream.flush();
745
746 string line1;
747 std::getline(request_stream,line1);
748 if (!request_stream) {
749 emit warning(QString::fromStdString("Fail to fetch certificate directory! #2"));
750 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800751 }
752
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700753 std::stringstream response_stream(line1);
754 string http_version;
755 response_stream >> http_version;
756 unsigned int status_code;
757 response_stream >> status_code;
758 string status_message;
759 std::getline(response_stream,status_message);
760
761 if (!response_stream ||
762 http_version.substr(0,5) != "HTTP/") {
763 emit warning(QString::fromStdString("Fail to fetch certificate directory! #3"));
764 return;
765 }
766 if (status_code!=200) {
767 emit warning(QString::fromStdString("Fail to fetch certificate directory! #4"));
768 return;
769 }
770 vector<string> headers;
771 string header;
772 while (std::getline(request_stream, header) && header != "\r")
773 headers.push_back(header);
774
775 std::istreambuf_iterator<char> stream_iter (request_stream);
776 std::istreambuf_iterator<char> end_of_stream;
777
778 typedef boost::tokenizer< boost::escaped_list_separator<char>,
779 std::istreambuf_iterator<char> > tokenizer_t;
780 tokenizer_t certItems (stream_iter,
781 end_of_stream,
782 boost::escaped_list_separator<char>('\\', '\n', '"'));
783
784 for (tokenizer_t::iterator it = certItems.begin(); it != certItems.end (); it++)
785 if (!it->empty())
786 bufferedIdCertNames.push_back(*it);
787 }
788 catch(std::exception &e) {
789 emit warning(QString::fromStdString("Fail to fetch certificate directory! #N"));
790 }
791
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800792 {
793 boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
794 m_idCertCount = bufferedIdCertNames.size();
Yingdi Yuae8217c2013-11-09 00:03:26 -0800795 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800796 m_bufferedIdCerts.clear();
797
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700798 for (vector<string>::const_iterator it = bufferedIdCertNames.begin();
799 it != bufferedIdCertNames.end(); it++) {
800 Name certName(*it);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800801
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700802 Interest interest(certName);
803 interest.setInterestLifetime(time::milliseconds(1000));
804 interest.setMustBeFresh(true);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700805
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700806 OnDataValidated onValidated =
807 bind(&ContactManager::onIdentityCertValidated, this, _1);
808 OnDataValidationFailed onValidationFailed =
809 bind(&ContactManager::onIdentityCertValidationFailed, this, _1, _2);
810 TimeoutNotify timeoutNotify =
811 bind(&ContactManager::onIdentityCertTimeoutNotify, this, _1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800812
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700813 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
814 }
Yingdi Yuae8217c2013-11-09 00:03:26 -0800815}
816
Yingdi Yu72232692013-11-12 17:50:21 -0800817void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800818ContactManager::onFetchIdCert(const QString& qCertName)
Yingdi Yu72232692013-11-12 17:50:21 -0800819{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800820 Name certName(qCertName.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700821 if (m_bufferedIdCerts.find(certName) != m_bufferedIdCerts.end())
822 emit idCertReady(*m_bufferedIdCerts[certName]);
Yingdi Yu72232692013-11-12 17:50:21 -0800823}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800824
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800825void
826ContactManager::onAddFetchedContactIdCert(const QString& qCertName)
827{
828 Name certName(qCertName.toStdString());
829 Name identity = IdentityCertificate::certificateNameToPublicKeyName(certName).getPrefix(-1);
830
831 BufferedIdCerts::const_iterator it = m_bufferedIdCerts.find(certName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700832 if (it != m_bufferedIdCerts.end()) {
833 Contact contact(*it->second);
834 try {
835 m_contactStorage->addContact(contact);
836 m_bufferedIdCerts.erase(certName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800837
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700838 m_contactList.clear();
839 m_contactStorage->getAllContacts(m_contactList);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800840
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700841 onWaitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800842 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700843 catch(ContactStorage::Error& e) {
844 emit warning(QString::fromStdString(e.what()));
845 }
846 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800847 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700848 emit warning(QString("Failure: no information of %1")
849 .arg(QString::fromStdString(identity.toUri())));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800850}
851
852void
853ContactManager::onWaitForContactList()
854{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800855 QStringList aliasList;
856 QStringList idList;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700857 for (ContactList::const_iterator it = m_contactList.begin(); it != m_contactList.end(); it++) {
858 aliasList << QString((*it)->getAlias().c_str());
859 idList << QString((*it)->getNameSpace().toUri().c_str());
860 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700861
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800862 emit contactAliasListReady(aliasList);
863 emit contactIdListReady(idList);
864}
865
866void
867ContactManager::onWaitForContactInfo(const QString& identity)
868{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700869 for (ContactList::const_iterator it = m_contactList.begin(); it != m_contactList.end(); it++)
870 if ((*it)->getNameSpace().toUri() == identity.toStdString())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800871 emit contactInfoReady(QString((*it)->getNameSpace().toUri().c_str()),
872 QString((*it)->getName().c_str()),
873 QString((*it)->getInstitution().c_str()),
874 (*it)->isIntroducer());
875}
876
877void
878ContactManager::onRemoveContact(const QString& identity)
879{
880 m_contactStorage->removeContact(Name(identity.toStdString()));
881 m_contactList.clear();
882 m_contactStorage->getAllContacts(m_contactList);
883
884 onWaitForContactList();
885}
886
887void
888ContactManager::onUpdateAlias(const QString& identity, const QString& alias)
889{
890 m_contactStorage->updateAlias(Name(identity.toStdString()), alias.toStdString());
891 m_contactList.clear();
892 m_contactStorage->getAllContacts(m_contactList);
893
894 onWaitForContactList();
895}
896
897void
898ContactManager::onUpdateIsIntroducer(const QString& identity, bool isIntroducer)
899{
900 m_contactStorage->updateIsIntroducer(Name(identity.toStdString()), isIntroducer);
901}
902
903void
904ContactManager::onUpdateEndorseCertificate(const QString& identity)
905{
906 Name identityName(identity.toStdString());
907 shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identityName);
908
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700909 if (!static_cast<bool>(newEndorseCertificate))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800910 return;
911
912 m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identityName);
913
914 publishEndorseCertificateInDNS(*newEndorseCertificate);
915}
916
917} // namespace chronos
Yingdi Yufa4ce792014-02-06 18:09:22 -0800918
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700919
920#if WAF
921#include "contact-manager.moc"
Yingdi Yu42125862014-08-07 17:04:28 -0700922// #include "contact-manager.cpp.moc"
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700923#endif