Add TrustedContant and ContactStorage
Add tinyxml.py in waf-tools
diff --git a/src/contact-item.h b/src/contact-item.h
index 2940693..e681ba7 100644
--- a/src/contact-item.h
+++ b/src/contact-item.h
@@ -8,8 +8,8 @@
* Author: Yingdi Yu <yingdi@cs.ucla.edu>
*/
-#ifndef CONTACT_ITEM_H
-#define CONTACT_ITEM_H
+#ifndef LINKNDN_CONTACT_ITEM_H
+#define LINKNDN_CONTACT_ITEM_H
#include <ndn.cxx/data.h>
#include <vector>
@@ -17,7 +17,7 @@
class ContactItem
{
- typedef std::vector<Ptr<EndorseCertificate> > EndorseCertificateList;
+ typedef std::vector<ndn::Ptr<EndorseCertificate> > EndorseCertificateList;
public:
ContactItem(const EndorseCertificate& selfEndorseCertificate,
@@ -25,23 +25,31 @@
~ContactItem() {}
- const ndn::Name&
+ inline const EndorseCertificate&
+ getSelfEndorseCertificate() const
+ { return m_selfEndorseCertificate; }
+
+ inline const ndn::Name&
getNameSpace() const
{ return m_namespace; }
- const std::string&
+ inline const std::string&
getAlias() const
{ return m_alias; }
- const std::string&
+ inline const std::string&
getName() const
{ return m_name; }
- const std::string&
+ inline const std::string&
getInstitution() const
{ return m_institution; }
-private:
+ inline const ndn::Name
+ getPublicKeyName() const
+ { return m_selfEndorseCertificate.getPublicKeyName(); }
+
+protected:
EndorseCertificate m_selfEndorseCertificate;
ndn::Name m_namespace;
diff --git a/src/contact-storage.cpp b/src/contact-storage.cpp
new file mode 100644
index 0000000..f42ec21
--- /dev/null
+++ b/src/contact-storage.cpp
@@ -0,0 +1,215 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "contact-storage.h"
+#include "exception.h"
+
+#include <string>
+#include <boost/filesystem.hpp>
+
+using namespace std;
+using namespace ndn;
+namespace fs = boost::filesystem;
+
+
+const string INIT_TC_TABLE = "\
+CREATE TABLE IF NOT EXISTS \n \
+ TrustedContact( \n \
+ contact_namespace BLOB NOT NULL, \n \
+ contact_alias BLOB NOT NULL, \n \
+ self_certificate BLOB NOT NULL, \n \
+ trust_scope BLOB NOT NULL, \n \
+ \
+ PRIMARY KEY (contact_namespace) \n \
+ ); \n \
+ \
+CREATE INDEX tc_index ON TrustedContact(contact_namespace); \n \
+";
+
+const string INIT_NC_TABLE = "\
+CREATE TABLE IF NOT EXISTS \n \
+ NormalContact( \n \
+ contact_namespace BLOB NOT NULL, \n \
+ contact_alias BLOB NOT NULL, \n \
+ self_certificate BLOB NOT NULL, \n \
+ \
+ PRIMARY KEY (contact_namespace) \n \
+ ); \n \
+ \
+CREATE INDEX nc_index ON NormalContact(contact_namespace); \n \
+";
+
+ContactStorage::ContactStorage()
+{
+ fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
+ fs::create_directories (chronosDir);
+
+ int res = sqlite3_open((chronosDir / "chronos.db").c_str (), &m_db);
+ if (res != SQLITE_OK)
+ throw LnException("Chronos DB cannot be open/created");
+
+ // Check if TrustedContact table exists
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='TrustedContact'", -1, &stmt, 0);
+ res = sqlite3_step (stmt);
+
+ bool tcTableExist = false;
+ if (res == SQLITE_ROW)
+ tcTableExist = true;
+ sqlite3_finalize (stmt);
+
+ if(!tcTableExist)
+ {
+ char *errmsg = 0;
+ res = sqlite3_exec (m_db, INIT_TC_TABLE.c_str (), NULL, NULL, &errmsg);
+ if (res != SQLITE_OK && errmsg != 0)
+ throw LnException("Init \"error\" in TrustedContact");
+ sqlite3_finalize (stmt);
+ }
+
+ // Check if NormalContact table exists
+ sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='NormalContact'", -1, &stmt, 0);
+ res = sqlite3_step (stmt);
+
+ bool ncTableExist = false;
+ if (res == SQLITE_ROW)
+ ncTableExist = true;
+ sqlite3_finalize (stmt);
+
+ if(!ncTableExist)
+ {
+ char *errmsg = 0;
+ res = sqlite3_exec (m_db, INIT_NC_TABLE.c_str (), NULL, NULL, &errmsg);
+
+ if (res != SQLITE_OK && errmsg != 0)
+ throw LnException("Init \"error\" in NormalContact");
+ }
+}
+
+void
+ContactStorage::addTrustedContact(const TrustedContact& trustedContact)
+{
+ if(doesTrustedContactExist(trustedContact.getNameSpace()))
+ throw LnException("Trusted Contact has already existed");
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db,
+ "INSERT INTO TrustedContact (contact_namespace, contact_alias, self_certificate, trust_scope) values (?, ?, ?, ?)",
+ -1,
+ &stmt,
+ 0);
+
+ sqlite3_bind_text(stmt, 1, trustedContact.getNameSpace().toUri().c_str(), trustedContact.getNameSpace().toUri().size (), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, trustedContact.getAlias().c_str(), trustedContact.getAlias().size(), SQLITE_TRANSIENT);
+ Ptr<Blob> selfCertificateBlob = trustedContact.getSelfEndorseCertificate().encodeToWire();
+ sqlite3_bind_text(stmt, 3, selfCertificateBlob->buf(), selfCertificateBlob->size(), SQLITE_TRANSIENT);
+ Ptr<Blob> trustScopeBlob = trustedContact.getTrustScopeBlob();
+ sqlite3_bind_text(stmt, 4, trustScopeBlob->buf(), trustScopeBlob->size(),SQLITE_TRANSIENT);
+
+ int res = sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+}
+
+void
+ContactStorage::addNormalContact(const ContactItem& normalContact)
+{
+ if(doesNormalContactExist(normalContact.getNameSpace()))
+ throw LnException("Normal Contact has already existed");
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db,
+ "INSERT INTO NormalContact (contact_namespace, contact_alias, self_certificate) values (?, ?, ?)",
+ -1,
+ &stmt,
+ 0);
+
+ sqlite3_bind_text(stmt, 1, normalContact.getNameSpace().toUri().c_str(), normalContact.getNameSpace().toUri().size (), SQLITE_TRANSIENT);
+ sqlite3_bind_text(stmt, 2, normalContact.getAlias().c_str(), normalContact.getAlias().size(), SQLITE_TRANSIENT);
+ Ptr<Blob> selfCertificateBlob = normalContact.getSelfEndorseCertificate().encodeToWire();
+ sqlite3_bind_text(stmt, 3, selfCertificateBlob->buf(), selfCertificateBlob->size(), SQLITE_TRANSIENT);
+
+ int res = sqlite3_step (stmt);
+ sqlite3_finalize (stmt);
+}
+
+bool
+ContactStorage::doesContactExist(const Name& name, bool normal)
+{
+ bool result = false;
+
+ sqlite3_stmt *stmt;
+ if(normal)
+ sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM NormalContact WHERE contact_namespace=?", -1, &stmt, 0);
+ else
+ sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM TrustedContact WHERE contact_namespace=?", -1, &stmt, 0);
+ sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
+
+ int res = sqlite3_step (stmt);
+
+ if (res == SQLITE_ROW)
+ {
+ int countAll = sqlite3_column_int (stmt, 0);
+ if (countAll > 0)
+ result = true;
+ }
+ sqlite3_finalize (stmt);
+ return result;
+}
+
+vector<Ptr<TrustedContact> >
+ContactStorage::getAllTrustedContacts() const
+{
+ vector<Ptr<TrustedContact> > trustedContacts;
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db,
+ "SELECT contact_alias, self_certificate, trust_scope FROM TrustedContact",
+ -1,
+ &stmt,
+ 0);
+
+ while( sqlite3_step (stmt) == SQLITE_ROW)
+ {
+ string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+ Ptr<Blob> certBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
+ Ptr<Data> certData = Data::decodeFromWire(certBlob);
+ EndorseCertificate endorseCertificate(*certData);
+ string trustScope(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2)), sqlite3_column_bytes (stmt, 2));
+
+ trustedContacts.push_back(Ptr<TrustedContact>(new TrustedContact(endorseCertificate, trustScope, alias)));
+ }
+
+ return trustedContacts;
+}
+
+vector<Ptr<ContactItem> >
+ContactStorage::getAllNormalContacts() const
+{
+ vector<Ptr<ContactItem> > normalContacts;
+
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2 (m_db,
+ "SELECT contact_alias, self_certificate FROM NormalContact",
+ -1,
+ &stmt,
+ 0);
+
+ while( sqlite3_step (stmt) == SQLITE_ROW)
+ {
+ string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
+ Ptr<Blob> certBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
+ Ptr<Data> certData = Data::decodeFromWire(certBlob);
+ EndorseCertificate endorseCertificate(*certData);
+
+ normalContacts.push_back(Ptr<ContactItem>(new ContactItem(endorseCertificate, alias)));
+ }
+
+ return normalContacts;
+}
diff --git a/src/contact-storage.h b/src/contact-storage.h
new file mode 100644
index 0000000..eca65da
--- /dev/null
+++ b/src/contact-storage.h
@@ -0,0 +1,53 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef LINKNDN_CONTACT_STORAGE_H
+#define LINKNDN_CONTACT_STORAGE_H
+
+#include <sqlite3.h>
+#include "trusted-contact.h"
+#include "contact-item.h"
+
+class ContactStorage
+{
+public:
+ ContactStorage();
+
+ ~ContactStorage() {}
+
+ void
+ addTrustedContact(const TrustedContact& trustedContact);
+
+ void
+ addNormalContact(const ContactItem& contactItem);
+
+ std::vector<ndn::Ptr<TrustedContact> >
+ getAllTrustedContacts() const;
+
+ std::vector<ndn::Ptr<ContactItem> >
+ getAllNormalContacts() const;
+
+private:
+ inline bool
+ doesTrustedContactExist(const ndn::Name& name)
+ { return doesContactExist(name, false); }
+
+ inline bool
+ doesNormalContactExist(const ndn::Name& name)
+ { return doesContactExist(name, true); }
+
+ bool
+ doesContactExist(const ndn::Name& name, bool normal);
+
+private:
+ sqlite3 *m_db;
+};
+
+#endif
diff --git a/src/trusted-contact.cpp b/src/trusted-contact.cpp
new file mode 100644
index 0000000..b3271d2
--- /dev/null
+++ b/src/trusted-contact.cpp
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "trusted-contact.h"
+#include <tinyxml.h>
+
+using namespace std;
+using namespace ndn;
+
+TrustedContact::TrustedContact(const EndorseCertificate& selfEndorseCertificate,
+ const string& trustScope,
+ const string& alias)
+ : ContactItem(selfEndorseCertificate, alias)
+{
+ TiXmlDocument xmlDoc;
+ xmlDoc.Parse(trustScope.c_str());
+
+ TiXmlNode * it = xmlDoc.FirstChild();
+ while(it != NULL)
+ {
+ m_trustScope.push_back(Regex::fromXmlElement(dynamic_cast<TiXmlElement *>(it)));
+ it = it->NextSibling();
+ }
+}
+
+bool
+TrustedContact::canBeTrustedFor(const Name& name)
+{
+ vector<Ptr<Regex> >::iterator it = m_trustScope.begin();
+
+ for(; it != m_trustScope.end(); it++)
+ if((*it)->match(name))
+ return true;
+ return false;
+}
+
+Ptr<Blob>
+TrustedContact::getTrustScopeBlob() const
+{
+ ostringstream oss;
+ TiXmlDocument * xmlDoc = new TiXmlDocument();
+
+ vector<Ptr<Regex> >::const_iterator it = m_trustScope.begin();
+ for(; it != m_trustScope.end(); it++)
+ xmlDoc->LinkEndChild((*it)->toXmlElement());
+
+ oss << *xmlDoc;
+ return Ptr<Blob>(new Blob(oss.str().c_str(), oss.str().size()));
+}
diff --git a/src/trusted-contact.h b/src/trusted-contact.h
new file mode 100644
index 0000000..9f9121c
--- /dev/null
+++ b/src/trusted-contact.h
@@ -0,0 +1,40 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2013, Regents of the University of California
+ * Yingdi Yu
+ *
+ * BSD license, See the LICENSE file for more information
+ *
+ * Author: Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef LINKNDN_TRUSTED_CONTACT_H
+#define LINKNDN_TRUSTED_CONTACT_H
+
+#include "contact-item.h"
+#include <ndn.cxx/regex/regex.h>
+
+class TrustedContact : public ContactItem
+{
+public:
+ TrustedContact(const EndorseCertificate& selfEndorseCertificate,
+ const std::string& trustScope,
+ const std::string& alias = std::string());
+
+ ~TrustedContact() {}
+
+ void
+ addTrustScope(ndn::Ptr<ndn::Regex> nameSpace)
+ { m_trustScope.push_back(nameSpace); }
+
+ bool
+ canBeTrustedFor(const ndn::Name& name);
+
+ ndn::Ptr<ndn::Blob>
+ getTrustScopeBlob() const;
+
+private:
+ std::vector<ndn::Ptr<ndn::Regex> > m_trustScope;
+};
+
+#endif
diff --git a/waf-tools/tinyxml.py b/waf-tools/tinyxml.py
new file mode 100644
index 0000000..3908b38
--- /dev/null
+++ b/waf-tools/tinyxml.py
@@ -0,0 +1,76 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+'''
+
+When using this tool, the wscript will look like:
+
+ def options(opt):
+ opt.tool_options('tinyxml', tooldir=["waf-tools"])
+
+ def configure(conf):
+ conf.load('compiler_cxx tiny')
+
+ def build(bld):
+ bld(source='main.cpp', target='app', use='TINYXML')
+
+Options are generated, in order to specify the location of tinyxml includes/libraries.
+
+
+'''
+import sys
+import re
+from waflib import Utils,Logs,Errors
+from waflib.Configure import conf
+TINYXML_DIR=['/usr','/usr/local','/opt/local','/sw']
+TINYXML_VERSION_FILE='tinyxml.h'
+TINYXML_VERSION_CODE='''
+#include <iostream>
+#include <tinyxml.h>
+int main() { std::cout << TIXML_MAJOR_VERSION << "." << TIXML_MINOR_VERSION << "." << TIXML_PATCH_VERSION; }
+'''
+
+def options(opt):
+ opt.add_option('--tinyxml',type='string',default='',dest='tinyxml_dir',help='''path to where TinyXML is installed, e.g. /usr/local''')
+@conf
+def __tinyxml_get_version_file(self,dir):
+ try:
+ return self.root.find_dir(dir).find_node('%s/%s' % ('include', TINYXML_VERSION_FILE))
+ except:
+ return None
+@conf
+def tinyxml_get_version(self,dir):
+ val=self.check_cxx(fragment=TINYXML_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
+ return val
+@conf
+def tinyxml_get_root(self,*k,**kw):
+ root=k and k[0]or kw.get('path',None)
+ # Logs.pprint ('RED', ' %s' %root)
+ if root and self.__tinyxml_get_version_file(root):
+ return root
+ for dir in TINYXML_DIR:
+ if self.__tinyxml_get_version_file(dir):
+ return dir
+ if root:
+ self.fatal('TinyXML not found in %s'%root)
+ else:
+ self.fatal('TinyXML not found, please provide a --tinyxml argument (see help)')
+@conf
+def check_tinyxml(self,*k,**kw):
+ if not self.env['CXX']:
+ self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+ var=kw.get('uselib_store','TINYXML')
+ self.start_msg('Checking TinyXML')
+ root = self.tinyxml_get_root(*k,**kw);
+ self.env.TINYXML_VERSION=self.tinyxml_get_version(root)
+
+ self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include");
+ self.env['LIB_%s'%var] = "tinyxml"
+ self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
+
+ self.end_msg(self.env.TINYXML_VERSION)
+ if Logs.verbose:
+ Logs.pprint('CYAN',' TinyXML include : %s'%self.env['INCLUDES_%s'%var])
+ Logs.pprint('CYAN',' TinyXML lib : %s'%self.env['LIB_%s'%var])
+ Logs.pprint('CYAN',' TinyXML libpath : %s'%self.env['LIBPATH_%s'%var])
diff --git a/wscript b/wscript
index 15f0fcf..c949474 100644
--- a/wscript
+++ b/wscript
@@ -6,22 +6,19 @@
def options(opt):
opt.load('compiler_c compiler_cxx boost protoc qt4')
+
+ opt.load('tinyxml', tooldir=['waf-tools'])
def configure(conf):
- conf.load("compiler_c compiler_cxx")
+ conf.load("compiler_c compiler_cxx boost protoc qt4 tinyxml")
conf.add_supported_cxxflags (cxxflags = ['-O3', '-g'])
- conf.load('protoc')
-
- conf.load('qt4')
-
- conf.load('boost')
-
+ conf.check_tinyxml(path=conf.options.tinyxml_dir)
conf.check_cfg(package='libndn.cxx', args=['--cflags', '--libs'], uselib_store='NDNCXX', mandatory=True)
conf.check_cfg(package='sqlite3', args=['--cflags', '--libs'], uselib_store='SQLITE3', mandatory=True)
- conf.check_boost(lib='system random thread')
+ conf.check_boost(lib='system random thread filesystem')
conf.write_config_header('config.h')
@@ -33,7 +30,7 @@
defines = "WAF",
source = bld.path.ant_glob(['src/*.cpp', 'src/*.ui']),
includes = ".",
- use = "QTCORE QTGUI SQLITE3 NDNCXX",
+ use = "QTCORE QTGUI SQLITE3 NDNCXX TINYXML BOOST BOOST_FILESYSTEM",
)