blob: b98c40ae0c987e0c5b0ef20dda98f510df4605ba [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>
Qiuhan Ding0cfc1512015-02-17 17:44:11 -08009 * Qiuhan Ding <qiuhanding@cs.ucla.edu>
Yingdi Yu9236c432013-10-18 11:29:25 -070010 */
11
Yingdi Yuf8f572d2014-01-13 11:19:47 -080012#if __clang__
Yingdi Yuf8f572d2014-01-13 11:19:47 -080013#pragma clang diagnostic ignored "-Wtautological-compare"
Yingdi Yuf8f572d2014-01-13 11:19:47 -080014#endif
15
Yingdi Yu0b0a7362014-08-05 16:31:30 -070016#include "contact-manager.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080017#include <QStringList>
Yingdi Yu06f572b2014-03-11 15:46:10 -070018#include <QFile>
Yingdi Yu9236c432013-10-18 11:29:25 -070019
Yingdi Yu4685b1b2013-10-18 17:05:02 -070020#ifndef Q_MOC_RUN
Yingdi Yufa0b6a02014-04-30 14:26:42 -070021#include <ndn-cxx/util/crypto.hpp>
22#include <ndn-cxx/util/io.hpp>
23#include <ndn-cxx/security/sec-rule-relative.hpp>
24#include <ndn-cxx/security/validator-regex.hpp>
Yingdi Yu0b0a7362014-08-05 16:31:30 -070025#include "cryptopp.hpp"
Yingdi Yu348f5ea2014-03-01 14:47:25 -080026#include <boost/asio.hpp>
27#include <boost/tokenizer.hpp>
28#include <boost/filesystem.hpp>
Yingdi Yuec3d9a32013-10-18 18:35:09 -070029#include "logging.h"
Yingdi Yu4685b1b2013-10-18 17:05:02 -070030#endif
Yingdi Yu9236c432013-10-18 11:29:25 -070031
Yingdi Yu348f5ea2014-03-01 14:47:25 -080032namespace fs = boost::filesystem;
Yingdi Yu9236c432013-10-18 11:29:25 -070033
Yingdi Yueb692ac2015-02-10 18:46:18 -080034// INIT_LOGGER("chronochat.ContactManager");
Yingdi Yuec3d9a32013-10-18 18:35:09 -070035
Yingdi Yueb692ac2015-02-10 18:46:18 -080036namespace chronochat {
Yingdi Yu4685b1b2013-10-18 17:05:02 -070037
Yingdi Yu0b0a7362014-08-05 16:31:30 -070038using std::string;
39using std::map;
40using std::vector;
41
42using ndn::Face;
43using ndn::OBufferStream;
44using ndn::IdentityCertificate;
45using ndn::Validator;
46using ndn::ValidatorRegex;
47using ndn::SecRuleRelative;
48using ndn::OnDataValidated;
49using ndn::OnDataValidationFailed;
50using ndn::OnInterestValidated;
51using ndn::OnInterestValidationFailed;
Yingdi Yu17032f82014-03-25 15:48:23 -070052
Yingdi Yu348f5ea2014-03-01 14:47:25 -080053
Yingdi Yu2c9e7712014-10-20 11:55:05 -070054ContactManager::ContactManager(Face& face,
Yingdi Yufa4ce792014-02-06 18:09:22 -080055 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 Yu2c9e7712014-10-20 11:55:05 -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
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800160ContactManager::fetchEndorseCertificateInternal(const Name& identity, size_t 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
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800165 if(certIndex >= endorseCollection->getCollectionEntries().size())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800166 prepareEndorseInfo(identity);
167
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800168 Name interestName(endorseCollection->getCollectionEntries()[certIndex].certName);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800169
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 Yu2c9e7712014-10-20 11:55:05 -0700174 m_face.expressInterest(interest,
175 bind(&ContactManager::onEndorseCertificateInternal,
176 this, _1, _2, identity, certIndex,
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800177 endorseCollection->getCollectionEntries()[certIndex].hash),
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700178 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
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800188 shared_ptr<EndorseInfo> endorseInfo = make_shared<EndorseInfo>();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800189 m_bufferedContacts[identity].m_endorseInfo = endorseInfo;
190
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800191 map<string, size_t> endorseCount;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700192 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
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800197 size_t endorseCertCount = 0;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800198
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++) {
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700226 std::stringstream ss;
227 ss << endorseCount[pIt->first] << "/" << endorseCertCount;
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800228 endorseInfo->addEndorsement(pIt->first, pIt->second, ss.str());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700229 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800230
231 emit contactEndorseInfoReady (*endorseInfo);
232}
233
234void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700235ContactManager::onDnsSelfEndorseCertValidated(const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800236 const Name& identity)
237{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700238 try {
239 Data plainData;
240 plainData.wireDecode(data->getContent().blockFromValue());
241 shared_ptr<EndorseCertificate> selfEndorseCertificate =
242 make_shared<EndorseCertificate>(boost::cref(plainData));
243 if (Validator::verifySignature(plainData, selfEndorseCertificate->getPublicKeyInfo())) {
244 m_bufferedContacts[identity].m_selfEndorseCert = selfEndorseCertificate;
245 fetchCollectEndorse(identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800246 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700247 else
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800248 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700249 }
250 catch(Block::Error& e) {
251 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
252 }
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800253 catch(EndorseCertificate::Error& e) {
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700254 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
255 }
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800256 catch(Data::Error& e) {
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700257 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
258 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800259}
260
261void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700262ContactManager::onDnsSelfEndorseCertValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700263 const string& failInfo,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800264 const Name& identity)
265{
266 // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
267 // but let's stay with failure for now.
268 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
269}
270
271void
272ContactManager::onDnsSelfEndorseCertTimeoutNotify(const Interest& interest,
273 const Name& identity)
274{
275 // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
276 // but let's stay with failure for now.
277 emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
278}
279
280void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700281ContactManager::onDnsCollectEndorseValidated(const shared_ptr<const Data>& data,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800282 const Name& identity)
283{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800284 try {
285 shared_ptr<EndorseCollection> endorseCollection =
286 make_shared<EndorseCollection>(data->getContent());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700287 m_bufferedContacts[identity].m_endorseCollection = endorseCollection;
288 fetchEndorseCertificateInternal(identity, 0);
289 }
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800290 catch (tlv::Error) {
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800291 prepareEndorseInfo(identity);
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800292 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800293}
294
295void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700296ContactManager::onDnsCollectEndorseValidationFailed(const shared_ptr<const Data>& data,
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700297 const string& failInfo,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800298 const Name& identity)
299{
300 prepareEndorseInfo(identity);
301}
302
303void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700304ContactManager::onDnsCollectEndorseTimeoutNotify(const Interest& interest, const Name& identity)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800305{
306 // _LOG_DEBUG("onDnsCollectEndorseTimeoutNotify: " << interest.getName());
307 prepareEndorseInfo(identity);
308}
309
310void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700311ContactManager::onEndorseCertificateInternal(const Interest& interest, Data& data,
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800312 const Name& identity, size_t certIndex,
313 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,
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800336 size_t certIndex)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800337{
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{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800393 size_t 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
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800416 data->setContent(endorseCollection.wireEncode());
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700417 m_keyChain.signByIdentity(*data, m_identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800418
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700419 m_contactStorage->updateDnsOthersEndorse(*data);
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700420 m_face.put(*data);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800421}
422
423void
424ContactManager::onIdentityCertValidated(const shared_ptr<const Data>& data)
425{
426 shared_ptr<IdentityCertificate> cert = make_shared<IdentityCertificate>(boost::cref(*data));
427 m_bufferedIdCerts[cert->getName()] = cert;
428 decreaseIdCertCount();
429}
430
431void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700432ContactManager::onIdentityCertValidationFailed(const shared_ptr<const Data>& data,
433 const string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800434{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700435 // _LOG_DEBUG("ContactManager::onIdentityCertValidationFailed " << data->getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800436 decreaseIdCertCount();
437}
438
439void
440ContactManager::onIdentityCertTimeoutNotify(const Interest& interest)
441{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700442 // _LOG_DEBUG("ContactManager::onIdentityCertTimeoutNotify: " << interest.getName());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800443 decreaseIdCertCount();
444}
445
446void
447ContactManager::decreaseIdCertCount()
448{
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800449 size_t count;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800450 {
451 boost::recursive_mutex::scoped_lock lock(m_idCertCountMutex);
452 m_idCertCount--;
453 count = m_idCertCount;
454 }
455
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700456 if (count == 0) {
457 QStringList certNameList;
458 QStringList nameList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800459
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700460 for(BufferedIdCerts::const_iterator it = m_bufferedIdCerts.begin();
461 it != m_bufferedIdCerts.end(); it++) {
462 certNameList << QString::fromStdString(it->second->getName().toUri());
463 Profile profile(*(it->second));
464 nameList << QString::fromStdString(profile.get("name"));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800465 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700466
467 emit idCertNameListReady(certNameList);
468 emit nameListReady(nameList);
469 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800470}
471
Yingdi Yu76dd8002013-12-24 11:16:32 +0800472shared_ptr<EndorseCertificate>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800473ContactManager::getSignedSelfEndorseCertificate(const Profile& profile)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700474{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800475 Name certificateName = m_keyChain.getDefaultCertificateNameForIdentity(m_identity);
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700476
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800477 shared_ptr<IdentityCertificate> signingCert = m_keyChain.getCertificate(certificateName);
Yingdi Yu72781e52013-11-06 23:00:21 -0800478
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700479 vector<string> endorseList;
480 for (Profile::const_iterator it = profile.begin(); it != profile.end(); it++)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700481 endorseList.push_back(it->first);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700482
483 shared_ptr<EndorseCertificate> selfEndorseCertificate =
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700484 make_shared<EndorseCertificate>(boost::cref(*signingCert),
485 boost::cref(profile),
486 boost::cref(endorseList));
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700487
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800488 m_keyChain.sign(*selfEndorseCertificate, certificateName);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700489
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800490 return selfEndorseCertificate;
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700491}
492
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700493void
Yingdi Yu76dd8002013-12-24 11:16:32 +0800494ContactManager::publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700495{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800496 Name dnsName = m_identity;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800497 dnsName.append("DNS").append("PROFILE").appendVersion();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800498
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700499 shared_ptr<Data> data = make_shared<Data>();
500 data->setName(dnsName);
501 data->setContent(selfEndorseCertificate.wireEncode());
502 data->setFreshnessPeriod(time::milliseconds(1000));
Yingdi Yu76dd8002013-12-24 11:16:32 +0800503
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700504 m_keyChain.signByIdentity(*data, m_identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800505
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700506 m_contactStorage->updateDnsSelfProfileData(*data);
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700507 m_face.put(*data);
Yingdi Yu4685b1b2013-10-18 17:05:02 -0700508}
509
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700510shared_ptr<EndorseCertificate>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800511ContactManager::generateEndorseCertificate(const Name& identity)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800512{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800513 shared_ptr<Contact> contact = getContact(identity);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700514 if (!static_cast<bool>(contact))
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800515 return shared_ptr<EndorseCertificate>();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800516
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800517 Name signerKeyName = m_keyChain.getDefaultKeyNameForIdentity(m_identity);
518
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700519 vector<string> endorseList;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800520 m_contactStorage->getEndorseList(identity, endorseList);
521
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700522 shared_ptr<EndorseCertificate> cert =
523 shared_ptr<EndorseCertificate>(new EndorseCertificate(contact->getPublicKeyName(),
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800524 contact->getPublicKey(),
525 contact->getNotBefore(),
526 contact->getNotAfter(),
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700527 signerKeyName,
528 contact->getProfile(),
529 endorseList));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800530 m_keyChain.signByIdentity(*cert, m_identity);
531 return cert;
532
533}
534
535void
536ContactManager::publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate)
537{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800538 Name endorsee = endorseCertificate.getPublicKeyName().getPrefix(-1);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800539 Name dnsName = m_identity;
540 dnsName.append("DNS")
541 .append(endorsee.wireEncode())
542 .append("ENDORSEE")
543 .appendVersion();
Yingdi Yub2e747d2013-11-05 23:06:43 -0800544
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700545 shared_ptr<Data> data = make_shared<Data>();
546 data->setName(dnsName);
547 data->setContent(endorseCertificate.wireEncode());
Yingdi Yub2e747d2013-11-05 23:06:43 -0800548
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700549 m_keyChain.signByIdentity(*data, m_identity);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800550
Yingdi Yu6c3c5962014-09-09 16:52:38 -0700551 m_contactStorage->updateDnsEndorseOthers(*data, dnsName.get(-3).toUri());
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700552 m_face.put(*data);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800553}
554
555void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800556ContactManager::sendInterest(const Interest& interest,
557 const OnDataValidated& onValidated,
558 const OnDataValidationFailed& onValidationFailed,
559 const TimeoutNotify& timeoutNotify,
560 int retry /* = 1 */)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800561{
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700562 m_face.expressInterest(interest,
563 bind(&ContactManager::onTargetData,
564 this, _1, _2, onValidated, onValidationFailed),
565 bind(&ContactManager::onTargetTimeout,
566 this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800567}
Yingdi Yu76dd8002013-12-24 11:16:32 +0800568
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800569void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700570ContactManager::onTargetData(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800571 const Data& data,
572 const OnDataValidated& onValidated,
573 const OnDataValidationFailed& onValidationFailed)
574{
575 // _LOG_DEBUG("On receiving data: " << data.getName());
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700576 m_validator->validate(data, onValidated, onValidationFailed);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800577}
Yingdi Yub2e747d2013-11-05 23:06:43 -0800578
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800579void
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700580ContactManager::onTargetTimeout(const Interest& interest,
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800581 int retry,
582 const OnDataValidated& onValidated,
583 const OnDataValidationFailed& onValidationFailed,
584 const TimeoutNotify& timeoutNotify)
585{
586 // _LOG_DEBUG("On interest timeout: " << interest.getName());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700587 if (retry > 0)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800588 sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, retry-1);
589 else
590 timeoutNotify(interest);
591}
592
593void
594ContactManager::onDnsInterest(const Name& prefix, const Interest& interest)
595{
596 const Name& interestName = interest.getName();
597 shared_ptr<Data> data;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700598
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700599 if (interestName.size() <= prefix.size())
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800600 return;
601
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700602 if (interestName.size() == (prefix.size()+1)) {
603 data = m_contactStorage->getDnsData("N/A", interestName.get(prefix.size()).toUri());
604 if (static_cast<bool>(data))
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700605 m_face.put(*data);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700606 return;
607 }
Yingdi Yub2e747d2013-11-05 23:06:43 -0800608
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700609 if (interestName.size() == (prefix.size()+2)) {
610 data = m_contactStorage->getDnsData(interestName.get(prefix.size()).toUri(),
611 interestName.get(prefix.size()+1).toUri());
612 if (static_cast<bool>(data))
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700613 m_face.put(*data);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700614 return;
615 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800616}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700617
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800618void
Yingdi Yu17032f82014-03-25 15:48:23 -0700619ContactManager::onDnsRegisterFailed(const Name& prefix, const std::string& failInfo)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800620{
621 emit warning(QString(failInfo.c_str()));
622}
623
624
625// public slots
626void
627ContactManager::onIdentityUpdated(const QString& identity)
628{
629 m_identity = Name(identity.toStdString());
630
631 m_contactStorage = make_shared<ContactStorage>(m_identity);
632
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800633 Name dnsPrefix;
634 dnsPrefix.append(m_identity).append("DNS");
Yingdi Yu2c9e7712014-10-20 11:55:05 -0700635 const ndn::RegisteredPrefixId* dnsListenerId =
636 m_face.setInterestFilter(dnsPrefix,
637 bind(&ContactManager::onDnsInterest,
638 this, _1, _2),
639 bind(&ContactManager::onDnsRegisterFailed,
640 this, _1, _2));
641
642 if (m_dnsListenerId != 0)
643 m_face.unsetInterestFilter(m_dnsListenerId);
644
645 m_dnsListenerId = dnsListenerId;
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;
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800753 size_t status_code;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700754 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
Yingdi Yueb692ac2015-02-10 18:46:18 -0800914} // namespace chronochat
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