blob: 7653cd0883c7f2c1eb4289c325035c086d840680 [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 -080052static const uint8_t DNS_RP_SEPARATOR[2] = {0xF0, 0x2E}; // %F0.
53
Yingdi Yufa4ce792014-02-06 18:09:22 -080054ContactManager::ContactManager(shared_ptr<Face> face,
55 QObject* parent)
56 : QObject(parent)
Yingdi Yufa4ce792014-02-06 18:09:22 -080057 , m_face(face)
Yingdi Yu348f5ea2014-03-01 14:47:25 -080058 , m_dnsListenerId(0)
Yingdi Yufa4ce792014-02-06 18:09:22 -080059{
Yingdi Yu76dd8002013-12-24 11:16:32 +080060 initializeSecurity();
Yingdi Yu9236c432013-10-18 11:29:25 -070061}
62
63ContactManager::~ContactManager()
Yingdi Yu0b0a7362014-08-05 16:31:30 -070064{
65}
Yingdi Yu9236c432013-10-18 11:29:25 -070066
Yingdi Yu348f5ea2014-03-01 14:47:25 -080067// private methods
Yingdi Yu06f572b2014-03-11 15:46:10 -070068shared_ptr<IdentityCertificate>
69ContactManager::loadTrustAnchor()
70{
71 shared_ptr<IdentityCertificate> anchor;
72
73 QFile anchorFile(":/security/anchor.cert");
74
Yingdi Yu0b0a7362014-08-05 16:31:30 -070075 if (!anchorFile.open(QIODevice::ReadOnly)) {
76 emit warning(QString("Cannot load trust anchor!"));
77 return anchor;
78 }
Yingdi Yu06f572b2014-03-11 15:46:10 -070079
80 qint64 fileSize = anchorFile.size();
81 char* buf = new char[fileSize];
82 anchorFile.read(buf, fileSize);
83
Yingdi Yu0b0a7362014-08-05 16:31:30 -070084 try {
85 using namespace CryptoPP;
Yingdi Yu06f572b2014-03-11 15:46:10 -070086
Yingdi Yu0b0a7362014-08-05 16:31:30 -070087 OBufferStream os;
88 StringSource(reinterpret_cast<const uint8_t*>(buf), fileSize, true,
89 new Base64Decoder(new FileSink(os)));
90 anchor = make_shared<IdentityCertificate>();
91 anchor->wireDecode(Block(os.buf()));
92 }
93 catch (CryptoPP::Exception& e) {
94 emit warning(QString("Cannot load trust anchor!"));
95 }
96 catch (IdentityCertificate::Error& e) {
97 emit warning(QString("Cannot load trust anchor!"));
98 }
99 catch(Block::Error& e) {
100 emit warning(QString("Cannot load trust anchor!"));
101 }
Yingdi Yu06f572b2014-03-11 15:46:10 -0700102
103 delete [] buf;
104
105 return anchor;
106}
107
Yingdi Yu76dd8002013-12-24 11:16:32 +0800108void
109ContactManager::initializeSecurity()
110{
Yingdi Yu06f572b2014-03-11 15:46:10 -0700111 shared_ptr<IdentityCertificate> anchor = loadTrustAnchor();
Yingdi Yufa4ce792014-02-06 18:09:22 -0800112
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700113 shared_ptr<ValidatorRegex> validator = make_shared<ValidatorRegex>(boost::ref(*m_face));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800114 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><ENDORSED>",
115 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
116 "==", "\\1", "\\1\\2", true));
117 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><><ENDORSEE>",
118 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
119 "==", "\\1", "\\1\\2", true));
120 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><PROFILE>",
121 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
122 "==", "\\1", "\\1\\2", true));
123 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<PROFILE-CERT>]*)<PROFILE-CERT>",
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700124 "^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$",
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800125 "==", "\\1", "\\1\\2", true));
126 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
127 "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>$",
128 ">", "\\1\\2", "\\1", true));
129 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
130 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
131 "==", "\\1", "\\1\\2", true));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700132 validator->addDataVerificationRule(make_shared<SecRuleRelative>("^(<>*)$",
133 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800134 ">", "\\1", "\\1\\2", true));
135 validator->addTrustAnchor(anchor);
136 m_validator = validator;
Yingdi Yu76dd8002013-12-24 11:16:32 +0800137}
138
139void
Yingdi Yufa4ce792014-02-06 18:09:22 -0800140ContactManager::fetchCollectEndorse(const Name& identity)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800141{
142 Name interestName = identity;
143 interestName.append("DNS").append("ENDORSED");
144
Yingdi Yu76dd8002013-12-24 11:16:32 +0800145 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700146 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800147 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800148
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700149 OnDataValidated onValidated =
150 bind(&ContactManager::onDnsCollectEndorseValidated, this, _1, identity);
151 OnDataValidationFailed onValidationFailed =
152 bind(&ContactManager::onDnsCollectEndorseValidationFailed, this, _1, _2, identity);
153 TimeoutNotify timeoutNotify =
154 bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, _1, identity);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800155
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800156 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800157}
158
159void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800160ContactManager::fetchEndorseCertificateInternal(const Name& identity, int certIndex)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800161{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700162 shared_ptr<EndorseCollection> endorseCollection =
163 m_bufferedContacts[identity].m_endorseCollection;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800164
165 if(certIndex >= endorseCollection->endorsement_size())
166 prepareEndorseInfo(identity);
167
168 Name interestName(endorseCollection->endorsement(certIndex).certname());
169
Yingdi Yu76dd8002013-12-24 11:16:32 +0800170 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700171 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yufa4ce792014-02-06 18:09:22 -0800172 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800173
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800174 m_face->expressInterest(interest,
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700175 bind(&ContactManager::onEndorseCertificateInternal,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800176 this, _1, _2, identity, certIndex,
177 endorseCollection->endorsement(certIndex).hash()),
178 bind(&ContactManager::onEndorseCertificateInternalTimeout,
179 this, _1, identity, certIndex));
Yingdi Yu76dd8002013-12-24 11:16:32 +0800180}
181
Yingdi Yu76dd8002013-12-24 11:16:32 +0800182void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800183ContactManager::prepareEndorseInfo(const Name& identity)
Yingdi Yu76dd8002013-12-24 11:16:32 +0800184{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800185 // _LOG_DEBUG("prepareEndorseInfo");
186 const Profile& profile = m_bufferedContacts[identity].m_selfEndorseCert->getProfile();
Yingdi Yu76dd8002013-12-24 11:16:32 +0800187
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700188 shared_ptr<Chronos::EndorseInfo> endorseInfo = make_shared<Chronos::EndorseInfo>();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800189 m_bufferedContacts[identity].m_endorseInfo = endorseInfo;
190
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700191 map<string, int> endorseCount;
192 for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
193 // _LOG_DEBUG("prepareEndorseInfo: profile[" << pIt->first << "]: " << pIt->second);
194 endorseCount[pIt->first] = 0;
195 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800196
197 int endorseCertCount = 0;
198
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700199 vector<shared_ptr<EndorseCertificate> >::const_iterator cIt =
200 m_bufferedContacts[identity].m_endorseCertList.begin();
201 vector<shared_ptr<EndorseCertificate> >::const_iterator cEnd =
202 m_bufferedContacts[identity].m_endorseCertList.end();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800203
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700204 for (; cIt != cEnd; cIt++, endorseCertCount++) {
205 shared_ptr<Contact> contact = getContact((*cIt)->getSigner().getPrefix(-1));
206 if (!static_cast<bool>(contact))
207 continue;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700208
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700209 if (!contact->isIntroducer() ||
210 !contact->canBeTrustedFor(profile.getIdentityName()))
211 continue;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800212
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700213 if (!Validator::verifySignature(**cIt, contact->getPublicKey()))
214 continue;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800215
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700216 const Profile& tmpProfile = (*cIt)->getProfile();
217 if (tmpProfile != profile)
218 continue;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800219
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700220 const vector<string>& endorseList = (*cIt)->getEndorseList();
221 for (vector<string>::const_iterator eIt = endorseList.begin(); eIt != endorseList.end(); eIt++)
222 endorseCount[*eIt] += 1;
223 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800224
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700225 for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
226 Chronos::EndorseInfo::Endorsement* endorsement = endorseInfo->add_endorsement();
227 endorsement->set_type(pIt->first);
228 endorsement->set_value(pIt->second);
229 std::stringstream ss;
230 ss << endorseCount[pIt->first] << "/" << endorseCertCount;
231 endorsement->set_endorse(ss.str());
232 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800233
234 emit contactEndorseInfoReady (*endorseInfo);
235}
236
237void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700238ContactManager::onDnsSelfEndorseCertValidated(const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800239 const Name& identity)
240{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700241 try {
242 Data plainData;
243 plainData.wireDecode(data->getContent().blockFromValue());
244 shared_ptr<EndorseCertificate> selfEndorseCertificate =
245 make_shared<EndorseCertificate>(boost::cref(plainData));
246 if (Validator::verifySignature(plainData, selfEndorseCertificate->getPublicKeyInfo())) {
247 m_bufferedContacts[identity].m_selfEndorseCert = selfEndorseCertificate;
248 fetchCollectEndorse(identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800249 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700250 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800251 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700252 }
253 catch(Block::Error& e) {
254 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
255 }
256 catch(Data::Error& e) {
257 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
258 }
259 catch(EndorseCertificate::Error& e) {
260 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
261 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800262}
263
264void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700265ContactManager::onDnsSelfEndorseCertValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700266 const string& failInfo,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800267 const Name& identity)
268{
269 // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
270 // but let's stay with failure for now.
271 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
272}
273
274void
275ContactManager::onDnsSelfEndorseCertTimeoutNotify(const Interest& interest,
276 const Name& identity)
277{
278 // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
279 // but let's stay with failure for now.
280 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
281}
282
283void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700284ContactManager::onDnsCollectEndorseValidated(const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800285 const Name& identity)
286{
287 shared_ptr<EndorseCollection> endorseCollection = make_shared<EndorseCollection>();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700288 if (!endorseCollection->ParseFromArray(data->getContent().value(),
289 data->getContent().value_size())) {
290 m_bufferedContacts[identity].m_endorseCollection = endorseCollection;
291 fetchEndorseCertificateInternal(identity, 0);
292 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800293 else
294 prepareEndorseInfo(identity);
295}
296
297void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700298ContactManager::onDnsCollectEndorseValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700299 const string& failInfo,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800300 const Name& identity)
301{
302 prepareEndorseInfo(identity);
303}
304
305void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700306ContactManager::onDnsCollectEndorseTimeoutNotify(const Interest& interest, const Name& identity)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800307{
308 // _LOG_DEBUG("onDnsCollectEndorseTimeoutNotify: " << interest.getName());
309 prepareEndorseInfo(identity);
310}
311
312void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700313ContactManager::onEndorseCertificateInternal(const Interest& interest, Data& data,
314 const Name& identity, int certIndex, string hash)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800315{
Yingdi Yu17032f82014-03-25 15:48:23 -0700316 std::stringstream ss;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700317 {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800318 using namespace CryptoPP;
319
320 SHA256 hash;
321 StringSource(data.wireEncode().wire(), data.wireEncode().size(), true,
322 new HashFilter(hash, new FileSink(ss)));
323 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700324
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700325 if (ss.str() == hash) {
326 shared_ptr<EndorseCertificate> endorseCertificate =
327 make_shared<EndorseCertificate>(boost::cref(data));
328 m_bufferedContacts[identity].m_endorseCertList.push_back(endorseCertificate);
329 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800330
331 fetchEndorseCertificateInternal(identity, certIndex+1);
332}
333
334void
335ContactManager::onEndorseCertificateInternalTimeout(const Interest& interest,
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700336 const Name& identity,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800337 int certIndex)
338{
339 fetchEndorseCertificateInternal(identity, certIndex+1);
340}
341
342void
343ContactManager::collectEndorsement()
344{
345 {
346 boost::recursive_mutex::scoped_lock lock(m_collectCountMutex);
347 m_collectCount = m_contactList.size();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700348
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700349 for (ContactList::iterator it = m_contactList.begin(); it != m_contactList.end(); it++) {
350 Name interestName = (*it)->getNameSpace();
351 interestName.append("DNS").append(m_identity.wireEncode()).append("ENDORSEE");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800352
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700353 Interest interest(interestName);
354 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700355
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700356 OnDataValidated onValidated = bind(&ContactManager::onDnsEndorseeValidated, this, _1);
357 OnDataValidationFailed onValidationFailed =
358 bind(&ContactManager::onDnsEndorseeValidationFailed, this, _1, _2);
359 TimeoutNotify timeoutNotify = bind(&ContactManager::onDnsEndorseeTimeoutNotify, this, _1);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700360
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700361 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
362 }
Yingdi Yu76dd8002013-12-24 11:16:32 +0800363 }
364}
365
366void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800367ContactManager::onDnsEndorseeValidated(const shared_ptr<const Data>& data)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800368{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800369 Data endorseData;
370 endorseData.wireDecode(data->getContent().blockFromValue());
Yingdi Yu76dd8002013-12-24 11:16:32 +0800371
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800372 EndorseCertificate endorseCertificate(endorseData);
373 m_contactStorage->updateCollectEndorse(endorseCertificate);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800374
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800375 decreaseCollectStatus();
Yingdi Yu76dd8002013-12-24 11:16:32 +0800376}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800377
378void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700379ContactManager::onDnsEndorseeValidationFailed(const shared_ptr<const Data>& data,
380 const string& failInfo)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700381{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800382 decreaseCollectStatus();
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700383}
384
Yingdi Yub2e747d2013-11-05 23:06:43 -0800385void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800386ContactManager::onDnsEndorseeTimeoutNotify(const Interest& interest)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800387{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800388 decreaseCollectStatus();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800389}
390
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700391void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800392ContactManager::decreaseCollectStatus()
Yingdi Yub2e747d2013-11-05 23:06:43 -0800393{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700394 int count;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800395 {
396 boost::recursive_mutex::scoped_lock lock(m_collectCountMutex);
397 m_collectCount--;
398 count = m_collectCount;
399 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800400
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800401 if(count == 0)
402 publishCollectEndorsedDataInDNS();
403}
Yingdi Yub2e747d2013-11-05 23:06:43 -0800404
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800405void
406ContactManager::publishCollectEndorsedDataInDNS()
407{
408 Name dnsName = m_identity;
409 dnsName.append("DNS").append("ENDORSED").appendVersion();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800410
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800411 Data data;
412 data.setName(dnsName);
413
414 EndorseCollection endorseCollection;
415 m_contactStorage->getCollectEndorse(endorseCollection);
416
417 OBufferStream os;
418 endorseCollection.SerializeToOstream(&os);
419
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700420 data.setContent(os.buf());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800421 m_keyChain.signByIdentity(data, m_identity);
422
423 m_contactStorage->updateDnsOthersEndorse(data);
424 m_face->put(data);
425}
426
427void
428ContactManager::onIdentityCertValidated(const shared_ptr<const Data>& data)
429{
430 shared_ptr<IdentityCertificate> cert = make_shared<IdentityCertificate>(boost::cref(*data));
431 m_bufferedIdCerts[cert->getName()] = cert;
432 decreaseIdCertCount();
433}
434
435void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700436ContactManager::onIdentityCertValidationFailed(const shared_ptr<const Data>& data,
437 const string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800438{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700439 // _LOG_DEBUG("ContactManager::onIdentityCertValidationFailed " << data->getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800440 decreaseIdCertCount();
441}
442
443void
444ContactManager::onIdentityCertTimeoutNotify(const Interest& interest)
445{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700446 // _LOG_DEBUG("ContactManager::onIdentityCertTimeoutNotify: " << interest.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800447 decreaseIdCertCount();
448}
449
450void
451ContactManager::decreaseIdCertCount()
452{
453 int count;
454 {
455 boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
456 m_idCertCount--;
457 count = m_idCertCount;
458 }
459
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700460 if (count == 0) {
461 QStringList certNameList;
462 QStringList nameList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800463
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700464 for(BufferedIdCerts::const_iterator it = m_bufferedIdCerts.begin();
465 it != m_bufferedIdCerts.end(); it++) {
466 certNameList << QString::fromStdString(it->second->getName().toUri());
467 Profile profile(*(it->second));
468 nameList << QString::fromStdString(profile.get("name"));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800469 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700470
471 emit idCertNameListReady(certNameList);
472 emit nameListReady(nameList);
473 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800474}
475
Yingdi Yu76dd8002013-12-24 11:16:32 +0800476shared_ptr<EndorseCertificate>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800477ContactManager::getSignedSelfEndorseCertificate(const Profile& profile)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700478{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800479 Name certificateName = m_keyChain.getDefaultCertificateNameForIdentity(m_identity);
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700480
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800481 shared_ptr<IdentityCertificate> signingCert = m_keyChain.getCertificate(certificateName);
Yingdi Yu72781e52013-11-06 23:00:21 -0800482
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700483 vector<string> endorseList;
484 for (Profile::const_iterator it = profile.begin(); it != profile.end(); it++)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700485 endorseList.push_back(it->first);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700486
487 shared_ptr<EndorseCertificate> selfEndorseCertificate =
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700488 make_shared<EndorseCertificate>(boost::cref(*signingCert),
489 boost::cref(profile),
490 boost::cref(endorseList));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700491
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800492 m_keyChain.sign(*selfEndorseCertificate, certificateName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700493
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800494 return selfEndorseCertificate;
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700495}
496
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700497void
Yingdi Yu76dd8002013-12-24 11:16:32 +0800498ContactManager::publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700499{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800500 Name dnsName = m_identity;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800501 dnsName.append("DNS").append("PROFILE").appendVersion();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800502
503 Data data;
Yingdi Yu76dd8002013-12-24 11:16:32 +0800504 data.setName(dnsName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800505 data.setContent(selfEndorseCertificate.wireEncode());
Yingdi Yua7876722014-03-25 14:46:55 -0700506 data.setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu76dd8002013-12-24 11:16:32 +0800507
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800508 m_keyChain.signByIdentity(data, m_identity);
509
510 m_contactStorage->updateDnsSelfProfileData(data);
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800511 m_face->put(data);
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700512}
513
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700514shared_ptr<EndorseCertificate>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800515ContactManager::generateEndorseCertificate(const Name& identity)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800516{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800517 shared_ptr<Contact> contact = getContact(identity);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700518 if (!static_cast<bool>(contact))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800519 return shared_ptr<EndorseCertificate>();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800520
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800521 Name signerKeyName = m_keyChain.getDefaultKeyNameForIdentity(m_identity);
522
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700523 vector<string> endorseList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800524 m_contactStorage->getEndorseList(identity, endorseList);
525
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700526 shared_ptr<EndorseCertificate> cert =
527 shared_ptr<EndorseCertificate>(new EndorseCertificate(contact->getPublicKeyName(),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800528 contact->getPublicKey(),
529 contact->getNotBefore(),
530 contact->getNotAfter(),
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700531 signerKeyName,
532 contact->getProfile(),
533 endorseList));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800534 m_keyChain.signByIdentity(*cert, m_identity);
535 return cert;
536
537}
538
539void
540ContactManager::publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate)
541{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800542 Name endorsee = endorseCertificate.getPublicKeyName().getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800543 Name dnsName = m_identity;
544 dnsName.append("DNS")
545 .append(endorsee.wireEncode())
546 .append("ENDORSEE")
547 .appendVersion();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800548
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800549 Data data;
Yingdi Yu76dd8002013-12-24 11:16:32 +0800550 data.setName(dnsName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800551 data.setContent(endorseCertificate.wireEncode());
Yingdi Yub2e747d2013-11-05 23:06:43 -0800552
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800553 m_keyChain.signByIdentity(data, m_identity);
554
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700555 m_contactStorage->updateDnsEndorseOthers(data, dnsName.get(-3).toUri());
Yingdi Yuf8f572d2014-01-13 11:19:47 -0800556 m_face->put(data);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800557}
558
559void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800560ContactManager::sendInterest(const Interest& interest,
561 const OnDataValidated& onValidated,
562 const OnDataValidationFailed& onValidationFailed,
563 const TimeoutNotify& timeoutNotify,
564 int retry /* = 1 */)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800565{
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700566 m_face->expressInterest(interest,
567 bind(&ContactManager::onTargetData,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800568 this, _1, _2, onValidated, onValidationFailed),
569 bind(&ContactManager::onTargetTimeout,
570 this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
571}
Yingdi Yu76dd8002013-12-24 11:16:32 +0800572
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800573void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700574ContactManager::onTargetData(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800575 const Data& data,
576 const OnDataValidated& onValidated,
577 const OnDataValidationFailed& onValidationFailed)
578{
579 // _LOG_DEBUG("On receiving data: " << data.getName());
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700580 m_validator->validate(data, onValidated, onValidationFailed);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800581}
Yingdi Yub2e747d2013-11-05 23:06:43 -0800582
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800583void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700584ContactManager::onTargetTimeout(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800585 int retry,
586 const OnDataValidated& onValidated,
587 const OnDataValidationFailed& onValidationFailed,
588 const TimeoutNotify& timeoutNotify)
589{
590 // _LOG_DEBUG("On interest timeout: " << interest.getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700591 if (retry > 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800592 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, retry-1);
593 else
594 timeoutNotify(interest);
595}
596
597void
598ContactManager::onDnsInterest(const Name& prefix, const Interest& interest)
599{
600 const Name& interestName = interest.getName();
601 shared_ptr<Data> data;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700602
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700603 if (interestName.size() <= prefix.size())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800604 return;
605
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700606 if (interestName.size() == (prefix.size()+1)) {
607 data = m_contactStorage->getDnsData("N/A", interestName.get(prefix.size()).toUri());
608 if (static_cast<bool>(data))
609 m_face->put(*data);
610 return;
611 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800612
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700613 if (interestName.size() == (prefix.size()+2)) {
614 data = m_contactStorage->getDnsData(interestName.get(prefix.size()).toUri(),
615 interestName.get(prefix.size()+1).toUri());
616 if (static_cast<bool>(data))
617 m_face->put(*data);
618 return;
619 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800620}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700621
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800622void
Yingdi Yu17032f82014-03-25 15:48:23 -0700623ContactManager::onDnsRegisterFailed(const Name& prefix, const std::string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800624{
625 emit warning(QString(failInfo.c_str()));
626}
627
628
629// public slots
630void
631ContactManager::onIdentityUpdated(const QString& identity)
632{
633 m_identity = Name(identity.toStdString());
634
635 m_contactStorage = make_shared<ContactStorage>(m_identity);
636
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700637 if (m_dnsListenerId)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800638 m_face->unsetInterestFilter(m_dnsListenerId);
639
640 Name dnsPrefix;
641 dnsPrefix.append(m_identity).append("DNS");
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700642 m_dnsListenerId = m_face->setInterestFilter(dnsPrefix,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700643 bind(&ContactManager::onDnsInterest,
644 this, _1, _2),
645 bind(&ContactManager::onDnsRegisterFailed,
646 this, _1, _2));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800647
648 m_contactList.clear();
649 m_contactStorage->getAllContacts(m_contactList);
650
651 m_bufferedContacts.clear();
652
653 collectEndorsement();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800654}
655
Yingdi Yuae8217c2013-11-09 00:03:26 -0800656void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800657ContactManager::onFetchContactInfo(const QString& identity)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800658{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800659 // try to fetch self-endorse-certificate via DNS PROFILE first.
660 Name identityName(identity.toStdString());
661 Name interestName;
662 interestName.append(identityName).append("DNS").append("PROFILE");
Yingdi Yu76dd8002013-12-24 11:16:32 +0800663
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800664 // _LOG_DEBUG("onFetchContactInfo " << identity.toStdString() << " profile: " << interestName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700665
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800666 Interest interest(interestName);
Yingdi Yua7876722014-03-25 14:46:55 -0700667 interest.setInterestLifetime(time::milliseconds(1000));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800668 interest.setMustBeFresh(true);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800669
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700670 OnDataValidated onValidated =
671 bind(&ContactManager::onDnsSelfEndorseCertValidated, this, _1, identityName);
672 OnDataValidationFailed onValidationFailed =
673 bind(&ContactManager::onDnsSelfEndorseCertValidationFailed, this, _1, _2, identityName);
674 TimeoutNotify timeoutNotify =
675 bind(&ContactManager::onDnsSelfEndorseCertTimeoutNotify, this, _1, identityName);
Yingdi Yu76dd8002013-12-24 11:16:32 +0800676
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800677 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
678}
Yingdi Yu76dd8002013-12-24 11:16:32 +0800679
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800680void
681ContactManager::onAddFetchedContact(const QString& identity)
682{
683 // _LOG_DEBUG("onAddFetchedContact");
684
685 Name identityName(identity.toStdString());
686
687 BufferedContacts::const_iterator it = m_bufferedContacts.find(identityName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700688 if (it != m_bufferedContacts.end()) {
689 Contact contact(*(it->second.m_selfEndorseCert));
690 // _LOG_DEBUG("onAddFetchedContact: contact ready");
691 try {
692 m_contactStorage->addContact(contact);
693 m_bufferedContacts.erase(identityName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800694
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700695 m_contactList.clear();
696 m_contactStorage->getAllContacts(m_contactList);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800697
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700698 onWaitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800699 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700700 catch(ContactStorage::Error& e) {
701 emit warning(QString::fromStdString(e.what()));
702 }
703 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800704 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700705 emit warning(QString("Failure: no information of %1").arg(identity));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800706}
707
708void
709ContactManager::onUpdateProfile()
710{
711 // Get current profile;
712 shared_ptr<Profile> newProfile = m_contactStorage->getSelfProfile();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700713 if (!static_cast<bool>(newProfile))
Yingdi Yuae8217c2013-11-09 00:03:26 -0800714 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800715
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700716 // _LOG_DEBUG("ContactManager::onUpdateProfile: getProfile");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800717
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700718 shared_ptr<EndorseCertificate> newEndorseCertificate =
719 getSignedSelfEndorseCertificate(*newProfile);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800720
721 m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate);
722
723 publishSelfEndorseCertificateInDNS(*newEndorseCertificate);
724}
725
726void
727ContactManager::onRefreshBrowseContact()
728{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700729 vector<string> bufferedIdCertNames;
730 try {
731 using namespace boost::asio::ip;
732 tcp::iostream request_stream;
733 request_stream.expires_from_now(boost::posix_time::milliseconds(5000));
734 request_stream.connect("ndncert.named-data.net","80");
735 if (!request_stream) {
736 emit warning(QString::fromStdString("Fail to fetch certificate directory! #1"));
737 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800738 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700739
740 request_stream << "GET /cert/list/ HTTP/1.0\r\n";
741 request_stream << "Host: ndncert.named-data.net\r\n\r\n";
742 request_stream.flush();
743
744 string line1;
745 std::getline(request_stream,line1);
746 if (!request_stream) {
747 emit warning(QString::fromStdString("Fail to fetch certificate directory! #2"));
748 return;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800749 }
750
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700751 std::stringstream response_stream(line1);
752 string http_version;
753 response_stream >> http_version;
754 unsigned int status_code;
755 response_stream >> status_code;
756 string status_message;
757 std::getline(response_stream,status_message);
758
759 if (!response_stream ||
760 http_version.substr(0,5) != "HTTP/") {
761 emit warning(QString::fromStdString("Fail to fetch certificate directory! #3"));
762 return;
763 }
764 if (status_code!=200) {
765 emit warning(QString::fromStdString("Fail to fetch certificate directory! #4"));
766 return;
767 }
768 vector<string> headers;
769 string header;
770 while (std::getline(request_stream, header) && header != "\r")
771 headers.push_back(header);
772
773 std::istreambuf_iterator<char> stream_iter (request_stream);
774 std::istreambuf_iterator<char> end_of_stream;
775
776 typedef boost::tokenizer< boost::escaped_list_separator<char>,
777 std::istreambuf_iterator<char> > tokenizer_t;
778 tokenizer_t certItems (stream_iter,
779 end_of_stream,
780 boost::escaped_list_separator<char>('\\', '\n', '"'));
781
782 for (tokenizer_t::iterator it = certItems.begin(); it != certItems.end (); it++)
783 if (!it->empty())
784 bufferedIdCertNames.push_back(*it);
785 }
786 catch(std::exception &e) {
787 emit warning(QString::fromStdString("Fail to fetch certificate directory! #N"));
788 }
789
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800790 {
791 boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
792 m_idCertCount = bufferedIdCertNames.size();
Yingdi Yuae8217c2013-11-09 00:03:26 -0800793 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800794 m_bufferedIdCerts.clear();
795
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700796 for (vector<string>::const_iterator it = bufferedIdCertNames.begin();
797 it != bufferedIdCertNames.end(); it++) {
798 Name certName(*it);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800799
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700800 Interest interest(certName);
801 interest.setInterestLifetime(time::milliseconds(1000));
802 interest.setMustBeFresh(true);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700803
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700804 OnDataValidated onValidated =
805 bind(&ContactManager::onIdentityCertValidated, this, _1);
806 OnDataValidationFailed onValidationFailed =
807 bind(&ContactManager::onIdentityCertValidationFailed, this, _1, _2);
808 TimeoutNotify timeoutNotify =
809 bind(&ContactManager::onIdentityCertTimeoutNotify, this, _1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800810
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700811 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
812 }
Yingdi Yuae8217c2013-11-09 00:03:26 -0800813}
814
Yingdi Yu72232692013-11-12 17:50:21 -0800815void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800816ContactManager::onFetchIdCert(const QString& qCertName)
Yingdi Yu72232692013-11-12 17:50:21 -0800817{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800818 Name certName(qCertName.toStdString());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700819 if (m_bufferedIdCerts.find(certName) != m_bufferedIdCerts.end())
820 emit idCertReady(*m_bufferedIdCerts[certName]);
Yingdi Yu72232692013-11-12 17:50:21 -0800821}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800822
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800823void
824ContactManager::onAddFetchedContactIdCert(const QString& qCertName)
825{
826 Name certName(qCertName.toStdString());
827 Name identity = IdentityCertificate::certificateNameToPublicKeyName(certName).getPrefix(-1);
828
829 BufferedIdCerts::const_iterator it = m_bufferedIdCerts.find(certName);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700830 if (it != m_bufferedIdCerts.end()) {
831 Contact contact(*it->second);
832 try {
833 m_contactStorage->addContact(contact);
834 m_bufferedIdCerts.erase(certName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800835
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700836 m_contactList.clear();
837 m_contactStorage->getAllContacts(m_contactList);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800838
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700839 onWaitForContactList();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800840 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700841 catch(ContactStorage::Error& e) {
842 emit warning(QString::fromStdString(e.what()));
843 }
844 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800845 else
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700846 emit warning(QString("Failure: no information of %1")
847 .arg(QString::fromStdString(identity.toUri())));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800848}
849
850void
851ContactManager::onWaitForContactList()
852{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800853 QStringList aliasList;
854 QStringList idList;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700855 for (ContactList::const_iterator it = m_contactList.begin(); it != m_contactList.end(); it++) {
856 aliasList << QString((*it)->getAlias().c_str());
857 idList << QString((*it)->getNameSpace().toUri().c_str());
858 }
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700859
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800860 emit contactAliasListReady(aliasList);
861 emit contactIdListReady(idList);
862}
863
864void
865ContactManager::onWaitForContactInfo(const QString& identity)
866{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700867 for (ContactList::const_iterator it = m_contactList.begin(); it != m_contactList.end(); it++)
868 if ((*it)->getNameSpace().toUri() == identity.toStdString())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800869 emit contactInfoReady(QString((*it)->getNameSpace().toUri().c_str()),
870 QString((*it)->getName().c_str()),
871 QString((*it)->getInstitution().c_str()),
872 (*it)->isIntroducer());
873}
874
875void
876ContactManager::onRemoveContact(const QString& identity)
877{
878 m_contactStorage->removeContact(Name(identity.toStdString()));
879 m_contactList.clear();
880 m_contactStorage->getAllContacts(m_contactList);
881
882 onWaitForContactList();
883}
884
885void
886ContactManager::onUpdateAlias(const QString& identity, const QString& alias)
887{
888 m_contactStorage->updateAlias(Name(identity.toStdString()), alias.toStdString());
889 m_contactList.clear();
890 m_contactStorage->getAllContacts(m_contactList);
891
892 onWaitForContactList();
893}
894
895void
896ContactManager::onUpdateIsIntroducer(const QString& identity, bool isIntroducer)
897{
898 m_contactStorage->updateIsIntroducer(Name(identity.toStdString()), isIntroducer);
899}
900
901void
902ContactManager::onUpdateEndorseCertificate(const QString& identity)
903{
904 Name identityName(identity.toStdString());
905 shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identityName);
906
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700907 if (!static_cast<bool>(newEndorseCertificate))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800908 return;
909
910 m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identityName);
911
912 publishEndorseCertificateInDNS(*newEndorseCertificate);
913}
914
915} // namespace chronos
Yingdi Yufa4ce792014-02-06 18:09:22 -0800916
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700917
918#if WAF
919#include "contact-manager.moc"
920#include "contact-manager.cpp.moc"
921#endif