blob: f42ec211a70efaa08410287cd863e73e762281ff [file] [log] [blame]
Yingdi Yud04ed1a2013-10-14 14:07:03 -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
11#include "contact-storage.h"
12#include "exception.h"
13
14#include <string>
15#include <boost/filesystem.hpp>
16
17using namespace std;
18using namespace ndn;
19namespace fs = boost::filesystem;
20
21
22const string INIT_TC_TABLE = "\
23CREATE TABLE IF NOT EXISTS \n \
24 TrustedContact( \n \
25 contact_namespace BLOB NOT NULL, \n \
26 contact_alias BLOB NOT NULL, \n \
27 self_certificate BLOB NOT NULL, \n \
28 trust_scope BLOB NOT NULL, \n \
29 \
30 PRIMARY KEY (contact_namespace) \n \
31 ); \n \
32 \
33CREATE INDEX tc_index ON TrustedContact(contact_namespace); \n \
34";
35
36const string INIT_NC_TABLE = "\
37CREATE TABLE IF NOT EXISTS \n \
38 NormalContact( \n \
39 contact_namespace BLOB NOT NULL, \n \
40 contact_alias BLOB NOT NULL, \n \
41 self_certificate BLOB NOT NULL, \n \
42 \
43 PRIMARY KEY (contact_namespace) \n \
44 ); \n \
45 \
46CREATE INDEX nc_index ON NormalContact(contact_namespace); \n \
47";
48
49ContactStorage::ContactStorage()
50{
51 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
52 fs::create_directories (chronosDir);
53
54 int res = sqlite3_open((chronosDir / "chronos.db").c_str (), &m_db);
55 if (res != SQLITE_OK)
56 throw LnException("Chronos DB cannot be open/created");
57
58 // Check if TrustedContact table exists
59 sqlite3_stmt *stmt;
60 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='TrustedContact'", -1, &stmt, 0);
61 res = sqlite3_step (stmt);
62
63 bool tcTableExist = false;
64 if (res == SQLITE_ROW)
65 tcTableExist = true;
66 sqlite3_finalize (stmt);
67
68 if(!tcTableExist)
69 {
70 char *errmsg = 0;
71 res = sqlite3_exec (m_db, INIT_TC_TABLE.c_str (), NULL, NULL, &errmsg);
72 if (res != SQLITE_OK && errmsg != 0)
73 throw LnException("Init \"error\" in TrustedContact");
74 sqlite3_finalize (stmt);
75 }
76
77 // Check if NormalContact table exists
78 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='NormalContact'", -1, &stmt, 0);
79 res = sqlite3_step (stmt);
80
81 bool ncTableExist = false;
82 if (res == SQLITE_ROW)
83 ncTableExist = true;
84 sqlite3_finalize (stmt);
85
86 if(!ncTableExist)
87 {
88 char *errmsg = 0;
89 res = sqlite3_exec (m_db, INIT_NC_TABLE.c_str (), NULL, NULL, &errmsg);
90
91 if (res != SQLITE_OK && errmsg != 0)
92 throw LnException("Init \"error\" in NormalContact");
93 }
94}
95
96void
97ContactStorage::addTrustedContact(const TrustedContact& trustedContact)
98{
99 if(doesTrustedContactExist(trustedContact.getNameSpace()))
100 throw LnException("Trusted Contact has already existed");
101
102 sqlite3_stmt *stmt;
103 sqlite3_prepare_v2 (m_db,
104 "INSERT INTO TrustedContact (contact_namespace, contact_alias, self_certificate, trust_scope) values (?, ?, ?, ?)",
105 -1,
106 &stmt,
107 0);
108
109 sqlite3_bind_text(stmt, 1, trustedContact.getNameSpace().toUri().c_str(), trustedContact.getNameSpace().toUri().size (), SQLITE_TRANSIENT);
110 sqlite3_bind_text(stmt, 2, trustedContact.getAlias().c_str(), trustedContact.getAlias().size(), SQLITE_TRANSIENT);
111 Ptr<Blob> selfCertificateBlob = trustedContact.getSelfEndorseCertificate().encodeToWire();
112 sqlite3_bind_text(stmt, 3, selfCertificateBlob->buf(), selfCertificateBlob->size(), SQLITE_TRANSIENT);
113 Ptr<Blob> trustScopeBlob = trustedContact.getTrustScopeBlob();
114 sqlite3_bind_text(stmt, 4, trustScopeBlob->buf(), trustScopeBlob->size(),SQLITE_TRANSIENT);
115
116 int res = sqlite3_step (stmt);
117 sqlite3_finalize (stmt);
118}
119
120void
121ContactStorage::addNormalContact(const ContactItem& normalContact)
122{
123 if(doesNormalContactExist(normalContact.getNameSpace()))
124 throw LnException("Normal Contact has already existed");
125
126 sqlite3_stmt *stmt;
127 sqlite3_prepare_v2 (m_db,
128 "INSERT INTO NormalContact (contact_namespace, contact_alias, self_certificate) values (?, ?, ?)",
129 -1,
130 &stmt,
131 0);
132
133 sqlite3_bind_text(stmt, 1, normalContact.getNameSpace().toUri().c_str(), normalContact.getNameSpace().toUri().size (), SQLITE_TRANSIENT);
134 sqlite3_bind_text(stmt, 2, normalContact.getAlias().c_str(), normalContact.getAlias().size(), SQLITE_TRANSIENT);
135 Ptr<Blob> selfCertificateBlob = normalContact.getSelfEndorseCertificate().encodeToWire();
136 sqlite3_bind_text(stmt, 3, selfCertificateBlob->buf(), selfCertificateBlob->size(), SQLITE_TRANSIENT);
137
138 int res = sqlite3_step (stmt);
139 sqlite3_finalize (stmt);
140}
141
142bool
143ContactStorage::doesContactExist(const Name& name, bool normal)
144{
145 bool result = false;
146
147 sqlite3_stmt *stmt;
148 if(normal)
149 sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM NormalContact WHERE contact_namespace=?", -1, &stmt, 0);
150 else
151 sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM TrustedContact WHERE contact_namespace=?", -1, &stmt, 0);
152 sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
153
154 int res = sqlite3_step (stmt);
155
156 if (res == SQLITE_ROW)
157 {
158 int countAll = sqlite3_column_int (stmt, 0);
159 if (countAll > 0)
160 result = true;
161 }
162 sqlite3_finalize (stmt);
163 return result;
164}
165
166vector<Ptr<TrustedContact> >
167ContactStorage::getAllTrustedContacts() const
168{
169 vector<Ptr<TrustedContact> > trustedContacts;
170
171 sqlite3_stmt *stmt;
172 sqlite3_prepare_v2 (m_db,
173 "SELECT contact_alias, self_certificate, trust_scope FROM TrustedContact",
174 -1,
175 &stmt,
176 0);
177
178 while( sqlite3_step (stmt) == SQLITE_ROW)
179 {
180 string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
181 Ptr<Blob> certBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
182 Ptr<Data> certData = Data::decodeFromWire(certBlob);
183 EndorseCertificate endorseCertificate(*certData);
184 string trustScope(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2)), sqlite3_column_bytes (stmt, 2));
185
186 trustedContacts.push_back(Ptr<TrustedContact>(new TrustedContact(endorseCertificate, trustScope, alias)));
187 }
188
189 return trustedContacts;
190}
191
192vector<Ptr<ContactItem> >
193ContactStorage::getAllNormalContacts() const
194{
195 vector<Ptr<ContactItem> > normalContacts;
196
197 sqlite3_stmt *stmt;
198 sqlite3_prepare_v2 (m_db,
199 "SELECT contact_alias, self_certificate FROM NormalContact",
200 -1,
201 &stmt,
202 0);
203
204 while( sqlite3_step (stmt) == SQLITE_ROW)
205 {
206 string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
207 Ptr<Blob> certBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
208 Ptr<Data> certData = Data::decodeFromWire(certBlob);
209 EndorseCertificate endorseCertificate(*certData);
210
211 normalContacts.push_back(Ptr<ContactItem>(new ContactItem(endorseCertificate, alias)));
212 }
213
214 return normalContacts;
215}