blob: a6fec03a4c1a8d93711b50fe4c3c33933918d014 [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 Yufa4ce792014-02-06 18:09:22 -080053ContactManager::ContactManager(shared_ptr<Face> face,
54 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 Yufa0b6a02014-04-30 14:26:42 -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 Yu348f5ea2014-03-01 14:47:25 -0800173 m_face->expressInterest(interest,
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700174 bind(&ContactManager::onEndorseCertificateInternal,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800175 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 Yu348f5ea2014-03-01 14:47:25 -0800410 Data data;
411 data.setName(dnsName);
412
413 EndorseCollection endorseCollection;
414 m_contactStorage->getCollectEndorse(endorseCollection);
415
416 OBufferStream os;
417 endorseCollection.SerializeToOstream(&os);
418
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700419 data.setContent(os.buf());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800420 m_keyChain.signByIdentity(data, m_identity);
421
422 m_contactStorage->updateDnsOthersEndorse(data);
423 m_face->put(data);
424}
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
502 Data data;
Yingdi Yu76dd8002013-12-24 11:16:32 +0800503 data.setName(dnsName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800504 data.setContent(selfEndorseCertificate.wireEncode());
Yingdi Yua7876722014-03-25 14:46:55 -0700505 data.setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu76dd8002013-12-24 11:16:32 +0800506
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800507 m_keyChain.signByIdentity(data, m_identity);
508
509 m_contactStorage->updateDnsSelfProfileData(data);
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800510 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 Yu348f5ea2014-03-01 14:47:25 -0800548 Data data;
Yingdi Yu76dd8002013-12-24 11:16:32 +0800549 data.setName(dnsName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800550 data.setContent(endorseCertificate.wireEncode());
Yingdi Yub2e747d2013-11-05 23:06:43 -0800551
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800552 m_keyChain.signByIdentity(data, m_identity);
553
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700554 m_contactStorage->updateDnsEndorseOthers(data, dnsName.get(-3).toUri());
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800555 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 Yufa0b6a02014-04-30 14:26:42 -0700565 m_face->expressInterest(interest,
566 bind(&ContactManager::onTargetData,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800567 this, _1, _2, onValidated, onValidationFailed),
568 bind(&ContactManager::onTargetTimeout,
569 this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
570}
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))
608 m_face->put(*data);
609 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))
616 m_face->put(*data);
617 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 Yu0b0a7362014-08-05 16:31:30 -0700636 if (m_dnsListenerId)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800637 m_face->unsetInterestFilter(m_dnsListenerId);
638
639 Name dnsPrefix;
640 dnsPrefix.append(m_identity).append("DNS");
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700641 m_dnsListenerId = m_face->setInterestFilter(dnsPrefix,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700642 bind(&ContactManager::onDnsInterest,
643 this, _1, _2),
644 bind(&ContactManager::onDnsRegisterFailed,
645 this, _1, _2));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800646
647 m_contactList.clear();
648 m_contactStorage->getAllContacts(m_contactList);
649
650 m_bufferedContacts.clear();
651
652 collectEndorsement();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800653}
654
Yingdi Yuae8217c2013-11-09 00:03:26 -0800655void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800656ContactManager::onFetchContactInfo(const QString& identity)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800657{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800658 // try to fetch self-endorse-certificate via DNS PROFILE first.
659 Name identityName(identity.toStdString());
660 Name interestName;
661 interestName.append(identityName).append("DNS").append("PROFILE");
Yingdi Yu76dd8002013-12-24 11:16:32 +0800662
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800663 // _LOG_DEBUG("onFetchContactInfo " << identity.toStdString() << " profile: " << interestName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700664
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800665 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700666 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800667 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800668
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700669 OnDataValidated onValidated =
670 bind(&ContactManager::onDnsSelfEndorseCertValidated, this, _1, identityName);
671 OnDataValidationFailed onValidationFailed =
672 bind(&ContactManager::onDnsSelfEndorseCertValidationFailed, this, _1, _2, identityName);
673 TimeoutNotify timeoutNotify =
674 bind(&ContactManager::onDnsSelfEndorseCertTimeoutNotify, this, _1, identityName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800675
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800676 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
677}
Yingdi Yu76dd8002013-12-24 11:16:32 +0800678
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800679void
680ContactManager::onAddFetchedContact(const QString& identity)
681{
682 // _LOG_DEBUG("onAddFetchedContact");
683
684 Name identityName(identity.toStdString());
685
686 BufferedContacts::const_iterator it = m_bufferedContacts.find(identityName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700687 if (it != m_bufferedContacts.end()) {
688 Contact contact(*(it->second.m_selfEndorseCert));
689 // _LOG_DEBUG("onAddFetchedContact: contact ready");
690 try {
691 m_contactStorage->addContact(contact);
692 m_bufferedContacts.erase(identityName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800693
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700694 m_contactList.clear();
695 m_contactStorage->getAllContacts(m_contactList);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800696
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700697 onWaitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800698 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700699 catch(ContactStorage::Error& e) {
700 emit warning(QString::fromStdString(e.what()));
701 }
702 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800703 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700704 emit warning(QString("Failure: no information of %1").arg(identity));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800705}
706
707void
708ContactManager::onUpdateProfile()
709{
710 // Get current profile;
711 shared_ptr<Profile> newProfile = m_contactStorage->getSelfProfile();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700712 if (!static_cast<bool>(newProfile))
Yingdi Yuae8217c2013-11-09 00:03:26 -0800713 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800714
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700715 // _LOG_DEBUG("ContactManager::onUpdateProfile: getProfile");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800716
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700717 shared_ptr<EndorseCertificate> newEndorseCertificate =
718 getSignedSelfEndorseCertificate(*newProfile);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800719
720 m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate);
721
722 publishSelfEndorseCertificateInDNS(*newEndorseCertificate);
723}
724
725void
726ContactManager::onRefreshBrowseContact()
727{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700728 vector<string> bufferedIdCertNames;
729 try {
730 using namespace boost::asio::ip;
731 tcp::iostream request_stream;
732 request_stream.expires_from_now(boost::posix_time::milliseconds(5000));
733 request_stream.connect("ndncert.named-data.net","80");
734 if (!request_stream) {
735 emit warning(QString::fromStdString("Fail to fetch certificate directory! #1"));
736 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800737 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700738
739 request_stream << "GET /cert/list/ HTTP/1.0\r\n";
740 request_stream << "Host: ndncert.named-data.net\r\n\r\n";
741 request_stream.flush();
742
743 string line1;
744 std::getline(request_stream,line1);
745 if (!request_stream) {
746 emit warning(QString::fromStdString("Fail to fetch certificate directory! #2"));
747 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800748 }
749
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700750 std::stringstream response_stream(line1);
751 string http_version;
752 response_stream >> http_version;
753 unsigned int status_code;
754 response_stream >> status_code;
755 string status_message;
756 std::getline(response_stream,status_message);
757
758 if (!response_stream ||
759 http_version.substr(0,5) != "HTTP/") {
760 emit warning(QString::fromStdString("Fail to fetch certificate directory! #3"));
761 return;
762 }
763 if (status_code!=200) {
764 emit warning(QString::fromStdString("Fail to fetch certificate directory! #4"));
765 return;
766 }
767 vector<string> headers;
768 string header;
769 while (std::getline(request_stream, header) && header != "\r")
770 headers.push_back(header);
771
772 std::istreambuf_iterator<char> stream_iter (request_stream);
773 std::istreambuf_iterator<char> end_of_stream;
774
775 typedef boost::tokenizer< boost::escaped_list_separator<char>,
776 std::istreambuf_iterator<char> > tokenizer_t;
777 tokenizer_t certItems (stream_iter,
778 end_of_stream,
779 boost::escaped_list_separator<char>('\\', '\n', '"'));
780
781 for (tokenizer_t::iterator it = certItems.begin(); it != certItems.end (); it++)
782 if (!it->empty())
783 bufferedIdCertNames.push_back(*it);
784 }
785 catch(std::exception &e) {
786 emit warning(QString::fromStdString("Fail to fetch certificate directory! #N"));
787 }
788
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800789 {
790 boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
791 m_idCertCount = bufferedIdCertNames.size();
Yingdi Yuae8217c2013-11-09 00:03:26 -0800792 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800793 m_bufferedIdCerts.clear();
794
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700795 for (vector<string>::const_iterator it = bufferedIdCertNames.begin();
796 it != bufferedIdCertNames.end(); it++) {
797 Name certName(*it);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800798
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700799 Interest interest(certName);
800 interest.setInterestLifetime(time::milliseconds(1000));
801 interest.setMustBeFresh(true);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700802
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700803 OnDataValidated onValidated =
804 bind(&ContactManager::onIdentityCertValidated, this, _1);
805 OnDataValidationFailed onValidationFailed =
806 bind(&ContactManager::onIdentityCertValidationFailed, this, _1, _2);
807 TimeoutNotify timeoutNotify =
808 bind(&ContactManager::onIdentityCertTimeoutNotify, this, _1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800809
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700810 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
811 }
Yingdi Yuae8217c2013-11-09 00:03:26 -0800812}
813
Yingdi Yu72232692013-11-12 17:50:21 -0800814void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800815ContactManager::onFetchIdCert(const QString& qCertName)
Yingdi Yu72232692013-11-12 17:50:21 -0800816{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800817 Name certName(qCertName.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700818 if (m_bufferedIdCerts.find(certName) != m_bufferedIdCerts.end())
819 emit idCertReady(*m_bufferedIdCerts[certName]);
Yingdi Yu72232692013-11-12 17:50:21 -0800820}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800821
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800822void
823ContactManager::onAddFetchedContactIdCert(const QString& qCertName)
824{
825 Name certName(qCertName.toStdString());
826 Name identity = IdentityCertificate::certificateNameToPublicKeyName(certName).getPrefix(-1);
827
828 BufferedIdCerts::const_iterator it = m_bufferedIdCerts.find(certName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700829 if (it != m_bufferedIdCerts.end()) {
830 Contact contact(*it->second);
831 try {
832 m_contactStorage->addContact(contact);
833 m_bufferedIdCerts.erase(certName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800834
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700835 m_contactList.clear();
836 m_contactStorage->getAllContacts(m_contactList);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800837
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700838 onWaitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800839 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700840 catch(ContactStorage::Error& e) {
841 emit warning(QString::fromStdString(e.what()));
842 }
843 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800844 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700845 emit warning(QString("Failure: no information of %1")
846 .arg(QString::fromStdString(identity.toUri())));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800847}
848
849void
850ContactManager::onWaitForContactList()
851{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800852 QStringList aliasList;
853 QStringList idList;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700854 for (ContactList::const_iterator it = m_contactList.begin(); it != m_contactList.end(); it++) {
855 aliasList << QString((*it)->getAlias().c_str());
856 idList << QString((*it)->getNameSpace().toUri().c_str());
857 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700858
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800859 emit contactAliasListReady(aliasList);
860 emit contactIdListReady(idList);
861}
862
863void
864ContactManager::onWaitForContactInfo(const QString& identity)
865{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700866 for (ContactList::const_iterator it = m_contactList.begin(); it != m_contactList.end(); it++)
867 if ((*it)->getNameSpace().toUri() == identity.toStdString())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800868 emit contactInfoReady(QString((*it)->getNameSpace().toUri().c_str()),
869 QString((*it)->getName().c_str()),
870 QString((*it)->getInstitution().c_str()),
871 (*it)->isIntroducer());
872}
873
874void
875ContactManager::onRemoveContact(const QString& identity)
876{
877 m_contactStorage->removeContact(Name(identity.toStdString()));
878 m_contactList.clear();
879 m_contactStorage->getAllContacts(m_contactList);
880
881 onWaitForContactList();
882}
883
884void
885ContactManager::onUpdateAlias(const QString& identity, const QString& alias)
886{
887 m_contactStorage->updateAlias(Name(identity.toStdString()), alias.toStdString());
888 m_contactList.clear();
889 m_contactStorage->getAllContacts(m_contactList);
890
891 onWaitForContactList();
892}
893
894void
895ContactManager::onUpdateIsIntroducer(const QString& identity, bool isIntroducer)
896{
897 m_contactStorage->updateIsIntroducer(Name(identity.toStdString()), isIntroducer);
898}
899
900void
901ContactManager::onUpdateEndorseCertificate(const QString& identity)
902{
903 Name identityName(identity.toStdString());
904 shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identityName);
905
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700906 if (!static_cast<bool>(newEndorseCertificate))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800907 return;
908
909 m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identityName);
910
911 publishEndorseCertificateInDNS(*newEndorseCertificate);
912}
913
914} // namespace chronos
Yingdi Yufa4ce792014-02-06 18:09:22 -0800915
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700916
917#if WAF
918#include "contact-manager.moc"
Yingdi Yu42125862014-08-07 17:04:28 -0700919// #include "contact-manager.cpp.moc"
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700920#endif