blob: 9357bed7c2dcf6dec095d74a85f212f1ce4fd1d9 [file] [log] [blame]
Yingdi Yud04ed1a2013-10-14 14:07:03 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
Varun Patilb3d03b92021-01-08 17:09:32 +05303 * Copyright (c) 2013-2021, Regents of the University of California
4 * Yingdi Yu
Yingdi Yud04ed1a2013-10-14 14:07:03 -07005 *
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 * Author: Qiuhan Ding <qiuhanding@cs.ucla.edu>
Yingdi Yud04ed1a2013-10-14 14:07:03 -070010 */
11
Yingdi Yu0b0a7362014-08-05 16:31:30 -070012#include "contact-storage.hpp"
Davide Pesavento7676b562020-12-14 00:41:26 -050013
14#include <ndn-cxx/security/transform/buffer-source.hpp>
15#include <ndn-cxx/security/transform/digest-filter.hpp>
16#include <ndn-cxx/security/transform/hex-encode.hpp>
17#include <ndn-cxx/security/transform/stream-sink.hpp>
Yingdi Yud04ed1a2013-10-14 14:07:03 -070018
Varun Patila24bd3e2020-11-24 10:08:33 +053019#include <boost/filesystem.hpp>
Yingdi Yu0b0a7362014-08-05 16:31:30 -070020
Yingdi Yueb692ac2015-02-10 18:46:18 -080021namespace chronochat {
Yingdi Yu0b0a7362014-08-05 16:31:30 -070022
Yingdi Yud04ed1a2013-10-14 14:07:03 -070023namespace fs = boost::filesystem;
24
Yingdi Yu0b0a7362014-08-05 16:31:30 -070025using std::string;
26using std::vector;
Yingdi Yu3b318c12013-10-15 17:54:00 -070027
Yingdi Yu0b0a7362014-08-05 16:31:30 -070028// user's own profile;
29const string INIT_SP_TABLE =
30 "CREATE TABLE IF NOT EXISTS "
31 " SelfProfile( "
32 " profile_type BLOB NOT NULL, "
33 " profile_value BLOB NOT NULL, "
34 " PRIMARY KEY (profile_type) "
35 " ); "
36 "CREATE INDEX sp_index ON SelfProfile(profile_type); ";
Yingdi Yu17032f82014-03-25 15:48:23 -070037
Yingdi Yu0b0a7362014-08-05 16:31:30 -070038// user's self endorse cert;
39const string INIT_SE_TABLE =
40 "CREATE TABLE IF NOT EXISTS "
41 " SelfEndorse( "
42 " identity BLOB NOT NULL UNIQUE, "
43 " endorse_data BLOB NOT NULL, "
44 " PRIMARY KEY (identity) "
45 " ); "
46 "CREATE INDEX se_index ON SelfEndorse(identity); ";
Yingdi Yu3b318c12013-10-15 17:54:00 -070047
Yingdi Yu0b0a7362014-08-05 16:31:30 -070048// contact's basic info
49const string INIT_CONTACT_TABLE =
50 "CREATE TABLE IF NOT EXISTS "
51 " Contact( "
52 " contact_namespace BLOB NOT NULL, "
53 " contact_alias BLOB NOT NULL, "
54 " contact_keyName BLOB NOT NULL, "
55 " contact_key BLOB NOT NULL, "
56 " notBefore INTEGER DEFAULT 0, "
57 " notAfter INTEGER DEFAULT 0, "
58 " is_introducer INTEGER DEFAULT 0, "
59 " PRIMARY KEY (contact_namespace) "
60 " ); "
61 "CREATE INDEX contact_index ON Contact(contact_namespace); ";
Yingdi Yud04ed1a2013-10-14 14:07:03 -070062
Yingdi Yu0b0a7362014-08-05 16:31:30 -070063// contact's trust scope;
64const string INIT_TS_TABLE =
65 "CREATE TABLE IF NOT EXISTS "
66 " TrustScope( "
67 " id INTEGER PRIMARY KEY AUTOINCREMENT, "
68 " contact_namespace BLOB NOT NULL, "
69 " trust_scope BLOB NOT NULL "
70 " ); "
71 "CREATE INDEX ts_index ON TrustScope(contact_namespace); ";
Yingdi Yud04ed1a2013-10-14 14:07:03 -070072
Yingdi Yu0b0a7362014-08-05 16:31:30 -070073// contact's profile
74const string INIT_CP_TABLE =
75 "CREATE TABLE IF NOT EXISTS "
76 " ContactProfile( "
77 " profile_identity BLOB NOT NULL, "
78 " profile_type BLOB NOT NULL, "
79 " profile_value BLOB NOT NULL, "
80 " endorse INTEGER NOT NULL, "
81 " PRIMARY KEY (profile_identity, profile_type) "
82 " ); "
83 "CREATE INDEX cp_index ON ContactProfile(profile_identity); ";
Yingdi Yub2e747d2013-11-05 23:06:43 -080084
Yingdi Yu0b0a7362014-08-05 16:31:30 -070085// user's endorsement on contacts
86const string INIT_PE_TABLE =
87 "CREATE TABLE IF NOT EXISTS "
88 " ProfileEndorse( "
89 " identity BLOB NOT NULL UNIQUE, "
90 " endorse_data BLOB NOT NULL, "
91 " PRIMARY KEY (identity) "
92 " ); "
93 "CREATE INDEX pe_index ON ProfileEndorse(identity); ";
Yingdi Yub2e747d2013-11-05 23:06:43 -080094
Yingdi Yu0b0a7362014-08-05 16:31:30 -070095// contact's endorsements on the user
96const string INIT_CE_TABLE =
97 "CREATE TABLE IF NOT EXISTS "
98 " CollectEndorse( "
99 " endorser BLOB NOT NULL, "
100 " endorse_name BLOB NOT NULL, "
101 " endorse_data BLOB NOT NULL, "
102 " PRIMARY KEY (endorser) "
103 " ); ";
Yingdi Yub2e747d2013-11-05 23:06:43 -0800104
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700105// dns data;
106const string INIT_DD_TABLE =
107 "CREATE TABLE IF NOT EXISTS "
108 " DnsData( "
109 " dns_name BLOB NOT NULL, "
110 " dns_type BLOB NOT NULL, "
111 " data_name BLOB NOT NULL, "
112 " dns_value BLOB NOT NULL, "
113 " PRIMARY KEY (dns_name, dns_type) "
114 " ); "
115 "CREATE INDEX dd_index ON DnsData(dns_name, dns_type); "
116 "CREATE INDEX dd_index2 ON DnsData(data_name); ";
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700117
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700118/**
119 * A utility function to call the normal sqlite3_bind_text where the value and length are
120 * value.c_str() and value.size().
121 */
122static int
123sqlite3_bind_string(sqlite3_stmt* statement,
124 int index,
125 const string& value,
126 void(*destructor)(void*))
127{
128 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
129}
130
131/**
132 * A utility function to call the normal sqlite3_bind_blob where the value and length are
133 * block.wire() and block.size().
134 */
135static int
136sqlite3_bind_block(sqlite3_stmt* statement,
137 int index,
138 const Block& block,
139 void(*destructor)(void*))
140{
141 return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
142}
143
144/**
145 * A utility function to generate string by calling the normal sqlite3_column_text.
146 */
147static string
148sqlite3_column_string(sqlite3_stmt* statement, int column)
149{
150 return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
151 sqlite3_column_bytes(statement, column));
152}
153
154/**
155 * A utility function to generate block by calling the normal sqlite3_column_text.
156 */
157static Block
158sqlite3_column_block(sqlite3_stmt* statement, int column)
159{
Varun Patil3d850902020-11-23 12:19:14 +0530160 return Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(statement, column)),
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700161 sqlite3_column_bytes(statement, column));
162}
163
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800164
165ContactStorage::ContactStorage(const Name& identity)
166 : m_identity(identity)
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700167{
168 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700169 fs::create_directories(chronosDir);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700170
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700171 int res = sqlite3_open((chronosDir / getDBName()).c_str(), &m_db);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700172 if (res != SQLITE_OK)
Varun Patila24bd3e2020-11-24 10:08:33 +0530173 NDN_THROW(Error("chronochat DB cannot be open/created"));
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700174
Yingdi Yufa4ce792014-02-06 18:09:22 -0800175 initializeTable("SelfProfile", INIT_SP_TABLE);
176 initializeTable("SelfEndorse", INIT_SE_TABLE);
177 initializeTable("Contact", INIT_CONTACT_TABLE);
178 initializeTable("TrustScope", INIT_TS_TABLE);
179 initializeTable("ContactProfile", INIT_CP_TABLE);
180 initializeTable("ProfileEndorse", INIT_PE_TABLE);
181 initializeTable("CollectEndorse", INIT_CE_TABLE);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800182 initializeTable("DnsData", INIT_DD_TABLE);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700183
Yingdi Yu3b318c12013-10-15 17:54:00 -0700184}
185
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700186string
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800187ContactStorage::getDBName()
188{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700189 string dbName("chronos-");
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800190
Davide Pesavento7676b562020-12-14 00:41:26 -0500191 std::ostringstream ss;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800192 {
Davide Pesavento7676b562020-12-14 00:41:26 -0500193 using namespace ndn::security::transform;
194 bufferSource(m_identity.wireEncode().wire(), m_identity.wireEncode().size())
195 >> digestFilter(ndn::DigestAlgorithm::SHA256)
196 >> hexEncode(false)
197 >> streamSink(ss);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800198 }
199 dbName.append(ss.str()).append(".db");
200
201 return dbName;
202}
203
Yingdi Yu3b318c12013-10-15 17:54:00 -0700204void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700205ContactStorage::initializeTable(const string& tableName, const string& sqlCreateStmt)
Yingdi Yu3b318c12013-10-15 17:54:00 -0700206{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800207 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700208 sqlite3_prepare_v2(m_db,
209 "SELECT name FROM sqlite_master WHERE type='table' And name=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500210 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700211 sqlite3_bind_string(stmt, 1, tableName, SQLITE_TRANSIENT);
212 int res = sqlite3_step(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800213
214 bool tableExist = false;
215 if (res == SQLITE_ROW)
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700216 tableExist = true;
217 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800218
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700219 if (!tableExist) {
Davide Pesavento7676b562020-12-14 00:41:26 -0500220 char *errmsg = nullptr;
Varun Patila24bd3e2020-11-24 10:08:33 +0530221 res = sqlite3_exec(m_db, sqlCreateStmt.c_str (), nullptr, nullptr, &errmsg);
Davide Pesavento7676b562020-12-14 00:41:26 -0500222 if (res != SQLITE_OK && errmsg != nullptr)
Varun Patila24bd3e2020-11-24 10:08:33 +0530223 NDN_THROW(Error("Init \"error\" in " + tableName));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700224 }
Yingdi Yu3b318c12013-10-15 17:54:00 -0700225}
226
Yingdi Yu76dd8002013-12-24 11:16:32 +0800227shared_ptr<Profile>
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800228ContactStorage::getSelfProfile()
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700229{
Varun Patilb3d03b92021-01-08 17:09:32 +0530230 auto profile = std::make_shared<Profile>(m_identity);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700231 sqlite3_stmt *stmt;
Davide Pesavento7676b562020-12-14 00:41:26 -0500232 sqlite3_prepare_v2(m_db, "SELECT profile_type, profile_value FROM SelfProfile",
233 -1, &stmt, nullptr);
Yingdi Yu2ac40fb2013-10-21 13:38:38 -0700234
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700235 while (sqlite3_step(stmt) == SQLITE_ROW) {
236 string profileType = sqlite3_column_string(stmt, 0);
237 string profileValue = sqlite3_column_string (stmt, 1);
238 (*profile)[profileType] = profileValue;
239 }
Yingdi Yu72781e52013-11-06 23:00:21 -0800240 sqlite3_finalize(stmt);
241
Yingdi Yu3b318c12013-10-15 17:54:00 -0700242 return profile;
243}
Yingdi Yuae8217c2013-11-09 00:03:26 -0800244
Yingdi Yufa4ce792014-02-06 18:09:22 -0800245void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800246ContactStorage::addSelfEndorseCertificate(const EndorseCertificate& newEndorseCertificate)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800247{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800248 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700249 sqlite3_prepare_v2(m_db,
250 "INSERT OR REPLACE INTO SelfEndorse (identity, endorse_data) values (?, ?)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500251 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700252 sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);
253 sqlite3_bind_block(stmt, 2, newEndorseCertificate.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700254 sqlite3_step(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800255
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700256 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800257}
258
Varun Patil3d850902020-11-23 12:19:14 +0530259shared_ptr<EndorseCertificate>
260ContactStorage::getSelfEndorseCertificate()
261{
262 shared_ptr<EndorseCertificate> cert;
263
264 sqlite3_stmt *stmt;
265 sqlite3_prepare_v2(m_db,
266 "SELECT endorse_data FROM SelfEndorse where identity=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500267 -1, &stmt, nullptr);
Varun Patil3d850902020-11-23 12:19:14 +0530268 sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);
269
270 if (sqlite3_step(stmt) == SQLITE_ROW) {
Varun Patilb3d03b92021-01-08 17:09:32 +0530271 cert = std::make_shared<EndorseCertificate>();
Varun Patil3d850902020-11-23 12:19:14 +0530272 cert->wireDecode(sqlite3_column_block(stmt, 0));
273 }
274
275 sqlite3_finalize(stmt);
276
277 return cert;
278}
279
Yingdi Yufa4ce792014-02-06 18:09:22 -0800280void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700281ContactStorage::addEndorseCertificate(const EndorseCertificate& endorseCertificate,
282 const Name& identity)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800283{
Yingdi Yufa4ce792014-02-06 18:09:22 -0800284 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700285 sqlite3_prepare_v2(m_db,
286 "INSERT OR REPLACE INTO ProfileEndorse \
287 (identity, endorse_data) values (?, ?)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500288 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700289 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
290 sqlite3_bind_block(stmt, 2, endorseCertificate.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800291 sqlite3_step(stmt);
292
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700293 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800294}
295
296void
297ContactStorage::updateCollectEndorse(const EndorseCertificate& endorseCertificate)
298{
299 Name endorserName = endorseCertificate.getSigner();
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800300 Name certName = endorseCertificate.getName();
Yingdi Yufa4ce792014-02-06 18:09:22 -0800301
302 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700303 sqlite3_prepare_v2(m_db,
304 "INSERT OR REPLACE INTO CollectEndorse \
305 (endorser, endorse_name, endorse_data) \
Varun Patil3d850902020-11-23 12:19:14 +0530306 VALUES (?, ?, ?)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500307 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700308 sqlite3_bind_string(stmt, 1, endorserName.toUri(), SQLITE_TRANSIENT);
309 sqlite3_bind_string(stmt, 2, certName.toUri(), SQLITE_TRANSIENT);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700310 sqlite3_bind_block(stmt, 3, endorseCertificate.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700311 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700312 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800313 return;
314}
315
316void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800317ContactStorage::getCollectEndorse(EndorseCollection& endorseCollection)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800318{
319 sqlite3_stmt *stmt;
Davide Pesavento7676b562020-12-14 00:41:26 -0500320 sqlite3_prepare_v2(m_db, "SELECT endorse_name, endorse_data FROM CollectEndorse",
321 -1, &stmt, nullptr);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800322
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700323 while (sqlite3_step(stmt) == SQLITE_ROW) {
324 string certName = sqlite3_column_string(stmt, 0);
Davide Pesavento7676b562020-12-14 00:41:26 -0500325 std::ostringstream ss;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800326 {
Davide Pesavento7676b562020-12-14 00:41:26 -0500327 using namespace ndn::security::transform;
328 bufferSource(sqlite3_column_text(stmt, 1), sqlite3_column_bytes(stmt, 1))
329 >> digestFilter(ndn::DigestAlgorithm::SHA256)
330 >> streamSink(ss);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800331 }
Qiuhan Ding0cfc1512015-02-17 17:44:11 -0800332 endorseCollection.addCollectionEntry(Name(certName), ss.str());
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700333 }
Yingdi Yufa4ce792014-02-06 18:09:22 -0800334
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700335 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800336}
337
Varun Patil3d850902020-11-23 12:19:14 +0530338shared_ptr<EndorseCertificate>
339ContactStorage::getCollectEndorseByName(const Name& name)
340{
341 shared_ptr<EndorseCertificate> cert;
342
343 sqlite3_stmt *stmt;
344 sqlite3_prepare_v2(m_db,
345 "SELECT endorse_name, endorse_data FROM CollectEndorse where endorse_name=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500346 -1, &stmt, nullptr);
Varun Patil3d850902020-11-23 12:19:14 +0530347 sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);
348
349 if (sqlite3_step(stmt) == SQLITE_ROW) {
Varun Patilb3d03b92021-01-08 17:09:32 +0530350 cert = std::make_shared<EndorseCertificate>();
Varun Patil3d850902020-11-23 12:19:14 +0530351 cert->wireDecode(sqlite3_column_block(stmt, 1));
352 }
353
354 sqlite3_finalize(stmt);
355
356 return cert;
357}
358
Yingdi Yufa4ce792014-02-06 18:09:22 -0800359void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700360ContactStorage::getEndorseList(const Name& identity, vector<string>& endorseList)
Yingdi Yufa4ce792014-02-06 18:09:22 -0800361{
362 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700363 sqlite3_prepare_v2(m_db,
364 "SELECT profile_type FROM ContactProfile \
365 WHERE profile_identity=? AND endorse=1 ORDER BY profile_type",
Davide Pesavento7676b562020-12-14 00:41:26 -0500366 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700367 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800368
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700369 while (sqlite3_step(stmt) == SQLITE_ROW) {
370 string profileType = sqlite3_column_string(stmt, 0);
371 endorseList.push_back(profileType);
372 }
373 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800374}
375
376
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700377void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800378ContactStorage::removeContact(const Name& identityName)
Yingdi Yuae8217c2013-11-09 00:03:26 -0800379{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700380 string identity = identityName.toUri();
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700381
382 sqlite3_stmt *stmt;
Davide Pesavento7676b562020-12-14 00:41:26 -0500383 sqlite3_prepare_v2(m_db, "DELETE FROM Contact WHERE contact_namespace=?", -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700384 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700385 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700386 sqlite3_finalize(stmt);
Yingdi Yuae8217c2013-11-09 00:03:26 -0800387
Davide Pesavento7676b562020-12-14 00:41:26 -0500388 sqlite3_prepare_v2(m_db, "DELETE FROM ContactProfile WHERE profile_identity=?", -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700389 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700390 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700391 sqlite3_finalize(stmt);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700392
Davide Pesavento7676b562020-12-14 00:41:26 -0500393 sqlite3_prepare_v2(m_db, "DELETE FROM TrustScope WHERE contact_namespace=?", -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700394 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700395 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700396 sqlite3_finalize(stmt);
Yingdi Yuae8217c2013-11-09 00:03:26 -0800397}
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700398
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700399void
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800400ContactStorage::addContact(const Contact& contact)
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700401{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700402 if (doesContactExist(contact.getNameSpace()))
Varun Patila24bd3e2020-11-24 10:08:33 +0530403 NDN_THROW(Error("Normal Contact has already existed"));
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700404
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700405 string identity = contact.getNameSpace().toUri();
Yingdi Yu71c01872013-11-03 16:22:05 -0800406 bool isIntroducer = contact.isIntroducer();
407
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700408 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700409 sqlite3_prepare_v2(m_db,
410 "INSERT INTO Contact (contact_namespace, contact_alias, contact_keyName, \
411 contact_key, notBefore, notAfter, is_introducer) \
412 values (?, ?, ?, ?, ?, ?, ?)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500413 -1, &stmt, nullptr);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700414
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700415 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
416 sqlite3_bind_string(stmt, 2, contact.getAlias(), SQLITE_TRANSIENT);
417 sqlite3_bind_string(stmt, 3, contact.getPublicKeyName().toUri(), SQLITE_TRANSIENT);
418 sqlite3_bind_text(stmt, 4,
Varun Patil3d850902020-11-23 12:19:14 +0530419 reinterpret_cast<const char*>(contact.getPublicKey().data()),
420 contact.getPublicKey().size(), SQLITE_TRANSIENT);
Yingdi Yua7876722014-03-25 14:46:55 -0700421 sqlite3_bind_int64(stmt, 5, time::toUnixTimestamp(contact.getNotBefore()).count());
422 sqlite3_bind_int64(stmt, 6, time::toUnixTimestamp(contact.getNotAfter()).count());
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800423 sqlite3_bind_int(stmt, 7, (isIntroducer ? 1 : 0));
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700424
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800425 sqlite3_step(stmt);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800426
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700427 sqlite3_finalize(stmt);
Yingdi Yu71c01872013-11-03 16:22:05 -0800428
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800429 const Profile& profile = contact.getProfile();
Davide Pesavento7676b562020-12-14 00:41:26 -0500430 for (auto it = profile.begin(); it != profile.end(); it++) {
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700431 sqlite3_prepare_v2(m_db,
432 "INSERT INTO ContactProfile \
433 (profile_identity, profile_type, profile_value, endorse) \
434 values (?, ?, ?, 0)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500435 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700436 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
437 sqlite3_bind_string(stmt, 2, it->first, SQLITE_TRANSIENT);
438 sqlite3_bind_string(stmt, 3, it->second, SQLITE_TRANSIENT);
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800439 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700440 sqlite3_finalize(stmt);
441 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800442
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700443 if (isIntroducer) {
Davide Pesavento7676b562020-12-14 00:41:26 -0500444 auto it = contact.trustScopeBegin();
445 auto end = contact.trustScopeEnd();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700446
447 while (it != end) {
448 sqlite3_prepare_v2(m_db,
449 "INSERT INTO TrustScope (contact_namespace, trust_scope) values (?, ?)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500450 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700451 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
452 sqlite3_bind_string(stmt, 2, it->first.toUri(), SQLITE_TRANSIENT);
Yingdi Yu1cc45d92015-02-09 14:19:54 -0800453 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700454 sqlite3_finalize(stmt);
455 it++;
Yingdi Yub2e747d2013-11-05 23:06:43 -0800456 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700457 }
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700458}
459
Yingdi Yufa4ce792014-02-06 18:09:22 -0800460
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800461shared_ptr<Contact>
462ContactStorage::getContact(const Name& identity) const
Yingdi Yufa4ce792014-02-06 18:09:22 -0800463{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800464 shared_ptr<Contact> contact;
465 Profile profile;
466
Yingdi Yufa4ce792014-02-06 18:09:22 -0800467 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700468 sqlite3_prepare_v2(m_db,
469 "SELECT contact_alias, contact_keyName, contact_key, notBefore, notAfter, \
470 is_introducer FROM Contact where contact_namespace=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500471 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700472 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800473
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700474 if (sqlite3_step(stmt) == SQLITE_ROW) {
475 string alias = sqlite3_column_string(stmt, 0);
476 string keyName = sqlite3_column_string(stmt, 1);
Varun Patil3d850902020-11-23 12:19:14 +0530477 ndn::Buffer key(sqlite3_column_text(stmt, 2), sqlite3_column_bytes (stmt, 2));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700478 time::system_clock::TimePoint notBefore =
479 time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 3)));
480 time::system_clock::TimePoint notAfter =
481 time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 4)));
482 int isIntroducer = sqlite3_column_int (stmt, 5);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800483
Varun Patilb3d03b92021-01-08 17:09:32 +0530484 contact = std::make_shared<Contact>(identity, alias, Name(keyName),
485 notBefore, notAfter, key, isIntroducer);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700486 }
487 sqlite3_finalize(stmt);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800488
Varun Patil3d850902020-11-23 12:19:14 +0530489 if (!static_cast<bool>(contact))
490 return contact;
491
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700492 sqlite3_prepare_v2(m_db,
493 "SELECT profile_type, profile_value FROM ContactProfile \
494 where profile_identity=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500495 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700496 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700497
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700498 while (sqlite3_step(stmt) == SQLITE_ROW) {
499 string type = sqlite3_column_string(stmt, 0);
500 string value = sqlite3_column_string(stmt, 1);
501 profile[type] = value;
502 }
503 sqlite3_finalize(stmt);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800504 contact->setProfile(profile);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800505
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700506 if (contact->isIntroducer()) {
507 sqlite3_prepare_v2(m_db,
508 "SELECT trust_scope FROM TrustScope WHERE contact_namespace=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500509 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700510 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa4ce792014-02-06 18:09:22 -0800511
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700512 while (sqlite3_step(stmt) == SQLITE_ROW) {
513 Name scope(sqlite3_column_string(stmt, 0));
514 contact->addTrustScope(scope);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800515 }
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700516 sqlite3_finalize(stmt);
517 }
Yingdi Yufa4ce792014-02-06 18:09:22 -0800518
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800519 return contact;
Yingdi Yufa4ce792014-02-06 18:09:22 -0800520}
521
522
Yingdi Yub2e747d2013-11-05 23:06:43 -0800523void
Yingdi Yufa4ce792014-02-06 18:09:22 -0800524ContactStorage::updateIsIntroducer(const Name& identity, bool isIntroducer)
Yingdi Yub2e747d2013-11-05 23:06:43 -0800525{
526 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700527 sqlite3_prepare_v2(m_db, "UPDATE Contact SET is_introducer=? WHERE contact_namespace=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500528 -1, &stmt, nullptr);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800529 sqlite3_bind_int(stmt, 1, (isIntroducer ? 1 : 0));
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700530 sqlite3_bind_string(stmt, 2, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700531 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700532 sqlite3_finalize(stmt);
Yingdi Yub2e747d2013-11-05 23:06:43 -0800533 return;
534}
535
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700536void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700537ContactStorage::updateAlias(const Name& identity, const string& alias)
Yingdi Yu2ac40fb2013-10-21 13:38:38 -0700538{
Yingdi Yu71c01872013-11-03 16:22:05 -0800539 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700540 sqlite3_prepare_v2(m_db, "UPDATE Contact SET contact_alias=? WHERE contact_namespace=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500541 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700542 sqlite3_bind_string(stmt, 1, alias, SQLITE_TRANSIENT);
543 sqlite3_bind_string(stmt, 2, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700544 sqlite3_step(stmt);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700545 sqlite3_finalize(stmt);
Yingdi Yu71c01872013-11-03 16:22:05 -0800546 return;
Yingdi Yu2ac40fb2013-10-21 13:38:38 -0700547}
548
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700549bool
Yingdi Yu71c01872013-11-03 16:22:05 -0800550ContactStorage::doesContactExist(const Name& name)
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700551{
552 bool result = false;
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700553
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700554 sqlite3_stmt *stmt;
Davide Pesavento7676b562020-12-14 00:41:26 -0500555 sqlite3_prepare_v2(m_db, "SELECT count(*) FROM Contact WHERE contact_namespace=?",
556 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700557 sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700558
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700559 int res = sqlite3_step(stmt);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700560
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700561 if (res == SQLITE_ROW) {
Davide Pesavento7676b562020-12-14 00:41:26 -0500562 int countAll = sqlite3_column_int(stmt, 0);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700563 if (countAll > 0)
564 result = true;
565 }
566
567 sqlite3_finalize(stmt);
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700568 return result;
569}
570
Yingdi Yu76dd8002013-12-24 11:16:32 +0800571void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700572ContactStorage::getAllContacts(vector<shared_ptr<Contact> >& contacts) const
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700573{
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700574 vector<Name> contactNames;
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800575
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700576 sqlite3_stmt *stmt;
Davide Pesavento7676b562020-12-14 00:41:26 -0500577 sqlite3_prepare_v2(m_db, "SELECT contact_namespace FROM Contact", -1, &stmt, nullptr);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700578
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700579 while (sqlite3_step(stmt) == SQLITE_ROW) {
580 string identity = sqlite3_column_string(stmt, 0);
581 contactNames.push_back(Name(identity));
582 }
583 sqlite3_finalize(stmt);
Yingdi Yu71c01872013-11-03 16:22:05 -0800584
Davide Pesavento7676b562020-12-14 00:41:26 -0500585 for (auto it = contactNames.begin(); it != contactNames.end(); it++) {
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700586 shared_ptr<Contact> contact = getContact(*it);
587 if (static_cast<bool>(contact))
588 contacts.push_back(contact);
589 }
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700590}
Yingdi Yu3b318c12013-10-15 17:54:00 -0700591
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800592void
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700593ContactStorage::updateDnsData(const Block& data, const string& name,
594 const string& type, const string& dataName)
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700595{
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800596 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700597 sqlite3_prepare_v2(m_db,
598 "INSERT OR REPLACE INTO DnsData (dns_name, dns_type, dns_value, data_name) \
599 VALUES (?, ?, ?, ?)",
Davide Pesavento7676b562020-12-14 00:41:26 -0500600 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700601 sqlite3_bind_string(stmt, 1, name, SQLITE_TRANSIENT);
602 sqlite3_bind_string(stmt, 2, type, SQLITE_TRANSIENT);
603 sqlite3_bind_block(stmt, 3, data, SQLITE_TRANSIENT);
604 sqlite3_bind_string(stmt, 4, dataName, SQLITE_TRANSIENT);
Yingdi Yu42125862014-08-07 17:04:28 -0700605 sqlite3_step(stmt);
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800606
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800607 sqlite3_finalize(stmt);
608}
609
610shared_ptr<Data>
611ContactStorage::getDnsData(const Name& dataName)
612{
613 shared_ptr<Data> data;
614
615 sqlite3_stmt *stmt;
Davide Pesavento7676b562020-12-14 00:41:26 -0500616 sqlite3_prepare_v2(m_db, "SELECT dns_value FROM DnsData where data_name=?", -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700617 sqlite3_bind_string(stmt, 1, dataName.toUri(), SQLITE_TRANSIENT);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700618
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700619 if (sqlite3_step(stmt) == SQLITE_ROW) {
Varun Patilb3d03b92021-01-08 17:09:32 +0530620 data = std::make_shared<Data>();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700621 data->wireDecode(sqlite3_column_block(stmt, 0));
622 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800623 sqlite3_finalize(stmt);
624
625 return data;
626}
627
628shared_ptr<Data>
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700629ContactStorage::getDnsData(const string& name, const string& type)
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800630{
631 shared_ptr<Data> data;
632
633 sqlite3_stmt *stmt;
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700634 sqlite3_prepare_v2(m_db, "SELECT dns_value FROM DnsData where dns_name=? and dns_type=?",
Davide Pesavento7676b562020-12-14 00:41:26 -0500635 -1, &stmt, nullptr);
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700636 sqlite3_bind_string(stmt, 1, name, SQLITE_TRANSIENT);
637 sqlite3_bind_string(stmt, 2, type, SQLITE_TRANSIENT);
Yingdi Yufa0b6a02014-04-30 14:26:42 -0700638
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700639 if (sqlite3_step(stmt) == SQLITE_ROW) {
Varun Patilb3d03b92021-01-08 17:09:32 +0530640 data = std::make_shared<Data>();
Yingdi Yu0b0a7362014-08-05 16:31:30 -0700641 data->wireDecode(sqlite3_column_block(stmt, 0));
642 }
Yingdi Yu348f5ea2014-03-01 14:47:25 -0800643 sqlite3_finalize(stmt);
644
645 return data;
646}
647
Yingdi Yueb692ac2015-02-10 18:46:18 -0800648} // namespace chronochat