summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanusz Kozerski <j.kozerski@samsung.com>2015-06-26 11:58:59 +0200
committerJanusz Kozerski <j.kozerski@samsung.com>2015-07-10 11:06:57 +0200
commit1bf0726b3028ddfaae0cdd70e46b416335da39a0 (patch)
tree3c4fff7b35b783a219f763315d4da94ef88137ad
parentaa31c0517333688b611ba453b08138960b53244e (diff)
downloadcert-checker-1bf0726b3028ddfaae0cdd70e46b416335da39a0.tar.gz
cert-checker-1bf0726b3028ddfaae0cdd70e46b416335da39a0.tar.bz2
cert-checker-1bf0726b3028ddfaae0cdd70e46b416335da39a0.zip
Refactor DB and app_t structure - preparation for OCSP checking.
New version of DB is needed to keep separately certificates from each signatrue. Because application can be signed by more than one signature we need to keep all certificates from all signatures in separate lists to make building certificates' chains easier. * Add operators (==, !=, <) for app_t structre * Add operators (==, !=) for event_t structure * Add tests for operators * Remove check_id from app_t structure Change-Id: I966dd81420618325d1afa55bcbc656291ccb4238
-rw-r--r--db/cert-checker.sql14
-rw-r--r--db/cert-checker.xml98
-rw-r--r--src/app.cpp24
-rw-r--r--src/certs.cpp9
-rw-r--r--src/db/sql_query.cpp124
-rw-r--r--src/include/cchecker/app.h18
-rw-r--r--src/include/cchecker/sql_query.h1
-rw-r--r--tests/CMakeLists.txt2
-rw-r--r--tests/app_event_operators.cpp86
-rw-r--r--tests/app_event_operators.h41
-rw-r--r--tests/test_app.cpp159
-rw-r--r--tests/test_db.cpp98
-rw-r--r--tests/test_queue.cpp50
13 files changed, 575 insertions, 149 deletions
diff --git a/db/cert-checker.sql b/db/cert-checker.sql
index 0103a49..2503e7c 100644
--- a/db/cert-checker.sql
+++ b/db/cert-checker.sql
@@ -21,13 +21,21 @@ CREATE TABLE IF NOT EXISTS ocsp_urls (
date INTEGER NOT NULL
);
+-- Table 'chains_to_check'
+CREATE TABLE IF NOT EXISTS chains_to_check (
+ chain_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ check_id INTEGER NOT NULL,
+
+ FOREIGN KEY (check_id) REFERENCES to_check(check_id) ON DELETE CASCADE
+);
+
-- Table 'certs_to_check'
CREATE TABLE IF NOT EXISTS certs_to_check (
- cert_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- check_id INTEGER NOT NULL,
+ chain_id INTEGER NOT NULL,
certificate TEXT NOT NULL,
- FOREIGN KEY (check_id) REFERENCES to_check(check_id) ON DELETE CASCADE
+ PRIMARY KEY (chain_id, certificate),
+ FOREIGN KEY (chain_id) REFERENCES chains_to_check(chain_id) ON DELETE CASCADE
);
COMMIT TRANSACTION;
diff --git a/db/cert-checker.xml b/db/cert-checker.xml
index c0221fc..e72b044 100644
--- a/db/cert-checker.xml
+++ b/db/cert-checker.xml
@@ -2,41 +2,41 @@
<!-- SQL XML created by WWW SQL Designer, http://code.google.com/p/wwwsqldesigner/ -->
<sql>
<datatypes db="mysql">
- <group label="Numeric" color="rgb(238,238,170)">
- <type label="TINYINT" length="0" sql="TINYINT" quote=""/>
- <type label="SMALLINT" length="0" sql="SMALLINT" quote=""/>
- <type label="MEDIUMINT" length="0" sql="MEDIUMINT" quote=""/>
- <type label="INT" length="0" sql="INT" quote=""/>
- <type label="Integer" length="0" sql="INTEGER" quote=""/>
- <type label="BIGINT" length="0" sql="BIGINT" quote=""/>
- <type label="Decimal" length="1" sql="DECIMAL" re="DEC" quote=""/>
- <type label="Single precision" length="0" sql="FLOAT" quote=""/>
- <type label="Double precision" length="0" sql="DOUBLE" re="DOUBLE" quote=""/>
- </group>
+ <group label="Numeric" color="rgb(238,238,170)">
+ <type label="TINYINT" length="0" sql="TINYINT" quote=""/>
+ <type label="SMALLINT" length="0" sql="SMALLINT" quote=""/>
+ <type label="MEDIUMINT" length="0" sql="MEDIUMINT" quote=""/>
+ <type label="INT" length="0" sql="INT" quote=""/>
+ <type label="Integer" length="0" sql="INTEGER" quote=""/>
+ <type label="BIGINT" length="0" sql="BIGINT" quote=""/>
+ <type label="Decimal" length="1" sql="DECIMAL" re="DEC" quote=""/>
+ <type label="Single precision" length="0" sql="FLOAT" quote=""/>
+ <type label="Double precision" length="0" sql="DOUBLE" re="DOUBLE" quote=""/>
+ </group>
- <group label="Character" color="rgb(255,200,200)">
- <type label="Char" length="1" sql="CHAR" quote="'"/>
- <type label="Varchar" length="1" sql="VARCHAR" quote="'"/>
- <type label="Text" length="0" sql="MEDIUMTEXT" re="TEXT" quote="'"/>
- <type label="Binary" length="1" sql="BINARY" quote="'"/>
- <type label="Varbinary" length="1" sql="VARBINARY" quote="'"/>
- <type label="BLOB" length="0" sql="BLOB" re="BLOB" quote="'"/>
- </group>
+ <group label="Character" color="rgb(255,200,200)">
+ <type label="Char" length="1" sql="CHAR" quote="'"/>
+ <type label="Varchar" length="1" sql="VARCHAR" quote="'"/>
+ <type label="Text" length="0" sql="MEDIUMTEXT" re="TEXT" quote="'"/>
+ <type label="Binary" length="1" sql="BINARY" quote="'"/>
+ <type label="Varbinary" length="1" sql="VARBINARY" quote="'"/>
+ <type label="BLOB" length="0" sql="BLOB" re="BLOB" quote="'"/>
+ </group>
- <group label="Date &amp; Time" color="rgb(200,255,200)">
- <type label="Date" length="0" sql="DATE" quote="'"/>
- <type label="Time" length="0" sql="TIME" quote="'"/>
- <type label="Datetime" length="0" sql="DATETIME" quote="'"/>
- <type label="Year" length="0" sql="YEAR" quote=""/>
- <type label="Timestamp" length="0" sql="TIMESTAMP" quote="'"/>
- </group>
-
- <group label="Miscellaneous" color="rgb(200,200,255)">
- <type label="ENUM" length="1" sql="ENUM" quote=""/>
- <type label="SET" length="1" sql="SET" quote=""/>
- <type label="Bit" length="0" sql="bit" quote=""/>
- </group>
-</datatypes><table x="760" y="211" name="to_check">
+ <group label="Date &amp; Time" color="rgb(200,255,200)">
+ <type label="Date" length="0" sql="DATE" quote="'"/>
+ <type label="Time" length="0" sql="TIME" quote="'"/>
+ <type label="Datetime" length="0" sql="DATETIME" quote="'"/>
+ <type label="Year" length="0" sql="YEAR" quote=""/>
+ <type label="Timestamp" length="0" sql="TIMESTAMP" quote="'"/>
+ </group>
+
+ <group label="Miscellaneous" color="rgb(200,200,255)">
+ <type label="ENUM" length="1" sql="ENUM" quote=""/>
+ <type label="SET" length="1" sql="SET" quote=""/>
+ <type label="Bit" length="0" sql="bit" quote=""/>
+ </group>
+</datatypes><table x="730" y="211" name="to_check">
<row name="check_id" null="0" autoincrement="1">
<datatype>INTEGER</datatype>
</row>
@@ -51,15 +51,12 @@
</row>
<row name="verified" null="0" autoincrement="0">
<datatype>INTEGER</datatype>
-<default>2</default></row>
+<default>NULL</default></row>
<key type="PRIMARY" name="">
<part>check_id</part>
</key>
</table>
-<table x="1132" y="211" name="ocsp_urls">
-<row name="url_id" null="0" autoincrement="1">
-<datatype>INTEGER</datatype>
-</row>
+<table x="1222" y="211" name="ocsp_urls">
<row name="issuer" null="0" autoincrement="0">
<datatype>MEDIUMTEXT</datatype>
</row>
@@ -70,21 +67,34 @@
<datatype>INT</datatype>
</row>
<key type="PRIMARY" name="">
-<part>url_id</part>
+<part>issuer</part>
+<part>url</part>
</key>
</table>
-<table x="928" y="211" name="certs_to_check">
+<table x="897" y="211" name="certs_to_check">
<row name="check_id" null="0" autoincrement="0">
<datatype>INTEGER</datatype>
<relation table="to_check" row="check_id" />
</row>
-<row name="certificate" null="0" autoincrement="0">
-<datatype>MEDIUMTEXT</datatype>
+<row name="chain_id" null="0" autoincrement="0">
+<datatype>INTEGER</datatype>
+<default>NULL</default><relation table="certs" row="chain_id" />
</row>
<key type="PRIMARY" name="">
<part>check_id</part>
-<part>certificate</part>
+<part>chain_id</part>
+</key>
+</table>
+<table x="1097" y="235" name="certs">
+<row name="chain_id" null="0" autoincrement="0">
+<datatype>INTEGER</datatype>
+<default>NULL</default></row>
+<row name="certificates" null="0" autoincrement="0">
+<datatype>MEDIUMTEXT</datatype>
+<default>'NULL'</default></row>
+<key type="PRIMARY" name="">
+<part>certificates</part>
+<part>chain_id</part>
</key>
</table>
</sql>
-
diff --git a/src/app.cpp b/src/app.cpp
index 58a7883..08b79a5 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -22,16 +22,14 @@
#include <sstream>
#include <string>
-#include <vector>
#include <sys/types.h>
#include <cchecker/app.h>
+#include <cchecker/log.h>
namespace CCHECKER {
app_t::app_t(void):
- check_id(-1), // -1 as invalid check_id - assume that in database
- // all check_ids will be positive
uid((uid_t)-1), // (uid_t)-1 (0xFF) is defined to be invalid uid. According
// to chown manual page, you cannot change file group of owner
// to (uid_t)-1, so we'll use it as initial, invalid value.
@@ -41,19 +39,17 @@ app_t::app_t(void):
app_t::app_t(const std::string &app_id,
const std::string &pkg_id,
uid_t uid,
- const std::vector<std::string> &certificates):
- check_id(-1),
+ const signatures_t &signatures):
app_id(app_id),
pkg_id(pkg_id),
uid(uid),
- certificates(certificates),
+ signatures(signatures),
verified(verified_t::UNKNOWN)
{}
std::ostream & operator<< (std::ostream &out, const app_t &app)
{
- out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid <<
- ", check_id: " << app.check_id;
+ out << "app: " << app.app_id << ", pkg: " << app.pkg_id << ", uid: " << app.uid;
return out;
}
@@ -64,4 +60,16 @@ std::string app_t::str() const
return ss.str();
}
+std::string app_t::str_certs(void) const
+{
+ std::stringstream ss;
+
+ for (const auto &iter : signatures) {
+ for (const auto iter_cert : iter) {
+ ss << "\"" << iter_cert << "\", ";
+ }
+ }
+ return ss.str();
+}
+
} //CCHECKER
diff --git a/src/certs.cpp b/src/certs.cpp
index 4a69fde..5b69ba0 100644
--- a/src/certs.cpp
+++ b/src/certs.cpp
@@ -119,7 +119,8 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u
LogDebug("Number of signature files: " << signature_files.size());
LogDebug("Searching for certificates");
- for (auto iter = signature_files.begin(); iter != signature_files.end(); iter++){
+ for (auto iter = signature_files.begin(); iter != signature_files.end(); iter++) {
+ chain_t chain;
LogDebug("Checking signature");
ValidationCore::SignatureData data(app_path + std::string("/") + (*iter).getFileName(),
(*iter).getFileNumber());
@@ -131,7 +132,7 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u
ValidationCore::CertificateList certs = data.getCertList();
for (auto cert_iter = certs.begin(); cert_iter != certs.end(); cert_iter++ ){
std::string app_cert = (*cert_iter)->getBase64();
- app.certificates.push_back(app_cert);
+ chain.push_back(app_cert);
LogDebug("Certificate: " << app_cert << " has been added");
// check OCSP URL
@@ -150,6 +151,10 @@ void Certs::find_app_signatures (app_t &app, const std::string &app_path, ocsp_u
// Needs to catch parser exceptions
LogError("Error occured in ParserSchema: " << exception.DumpToString());
}
+ if (!chain.empty()) {
+ app.signatures.push_back(chain);
+ LogDebug("Certificates chain added to the app");
+ }
}
}
diff --git a/src/db/sql_query.cpp b/src/db/sql_query.cpp
index 0968717..27eb52e 100644
--- a/src/db/sql_query.cpp
+++ b/src/db/sql_query.cpp
@@ -36,6 +36,12 @@ namespace {
// 107 - check_id
// 108 - certificate
// 109 - verified
+ // 110 - chain_id
+
+ // setup
+ const char *DB_CMD_SETUP = "VACUUM; PRAGMA foregin_keys=ON;";
+
+ const char *DB_CMD_GET_LAST_INSERTED_ROW = "SELECT last_insert_rowid();";
// urls
const char *DB_CMD_GET_URL =
@@ -54,17 +60,24 @@ namespace {
const char *DB_CMD_GET_CHECK_ID =
"SELECT check_id FROM to_check WHERE app_id=?104 AND pkg_id=?105 AND uid=?106;";
+ const char *DB_CMD_ADD_CHAIN =
+ "INSERT INTO chains_to_check(check_id) VALUES(?107);";
+
const char *DB_CMD_ADD_CERT =
- "INSERT INTO certs_to_check(check_id, certificate) VALUES(?107, ?108);";
+ "INSERT INTO certs_to_check(chain_id, certificate) VALUES(?110, ?108);";
+
+ const char *DB_CMD_GET_CHAINS =
+ "SELECT chain_id FROM chains_to_check INNER JOIN to_check ON chains_to_check.check_id=to_check.check_id \
+WHERE to_check.app_id=?104 AND to_check.pkg_id=?105 AND to_check.uid=?106;";
const char *DB_CMD_REMOVE_APP =
"DELETE FROM to_check WHERE app_id=?104 AND pkg_id=?105 AND uid=?106;";
const char *DB_CMD_GET_APPS =
- "SELECT * FROM to_check";
+ "SELECT app_id, pkg_id, uid, verified FROM to_check";
const char *DB_CMD_GET_CERTS =
- "SELECT certificate FROM certs_to_check WHERE check_id=?107;";
+ "SELECT certificate FROM certs_to_check WHERE chain_id=?110;";
const char *DB_CMD_SET_APP_AS_VERIFIED =
"UPDATE to_check SET verified=?109 WHERE check_id=?107";
@@ -91,7 +104,7 @@ bool SqlQuery::connect(const std::string& path)
Try {
m_connection = new SqlConnection(path, SqlConnection::Flag::None, SqlConnection::Flag::Option::CRW);
- m_connection->ExecCommand("VACUUM;");
+ m_connection->ExecCommand(DB_CMD_SETUP);
return true;
} Catch(std::bad_alloc) {
LogError("Couldn't allocate SqlConnection");
@@ -185,6 +198,25 @@ bool SqlQuery::get_check_id(const app_t &app, int32_t &check_id)
return false;
}
+bool SqlQuery::add_chain_id(const int32_t check_id, int32_t &chain_id)
+{
+ // Add new chain for an app
+ SqlConnection::DataCommandAutoPtr addChainCommand =
+ m_connection->PrepareDataCommand(DB_CMD_ADD_CHAIN);
+ addChainCommand->BindInt32(107, check_id);
+ addChainCommand->Step();
+
+ // get chain_id
+ SqlConnection::DataCommandAutoPtr getLastInserted =
+ m_connection->PrepareDataCommand(DB_CMD_GET_LAST_INSERTED_ROW);
+ if(getLastInserted->Step()) {
+ chain_id = getLastInserted->GetColumnInt32(0);
+ LogDebug("Found chain_id: " << chain_id << ", for check_id " << check_id);
+ return true;
+ }
+ return false;
+}
+
bool SqlQuery::add_app_to_check_list(const app_t &app)
{
//Check if app exists in DB
@@ -206,23 +238,35 @@ bool SqlQuery::add_app_to_check_list(const app_t &app)
// Get check_id
int32_t check_id;
- if (get_check_id(app, check_id)) {
- // If get check_id succeed we can add certificates to database
- for (const auto &iter : app.certificates) {
- SqlConnection::DataCommandAutoPtr addCertCommand =
- m_connection->PrepareDataCommand(DB_CMD_ADD_CERT);
- addCertCommand->BindInt32(107, check_id);
- addCertCommand->BindString(108, iter.c_str());
- addCertCommand->Step();
- LogDebug("Certificate for app " << app.app_id << "added");
- }
- m_connection->CommitTransaction();
- return true;
- } else { // If get check_id failed return false;
+ if (!get_check_id(app, check_id)) { // If get check_id failed return false;
LogDebug("Failed while addind app "<< app.app_id << " to to_check table.");
m_connection->RollbackTransaction();
return false;
}
+
+ // If get check_id succeed we can add chain to database
+ int32_t chain_id;
+ for (const auto &iter : app.signatures) {
+ // Add chain
+ if (add_chain_id(check_id, chain_id)) {
+ // add certificates from chain
+ for (const auto &iter_cert : iter) {
+ SqlConnection::DataCommandAutoPtr addCertCommand =
+ m_connection->PrepareDataCommand(DB_CMD_ADD_CERT);
+ addCertCommand->BindInt32(110, chain_id);
+ addCertCommand->BindString(108, iter_cert.c_str());
+ addCertCommand->Step();
+ LogDebug("Certificate for app " << app.app_id << "added");
+ }
+ } else {
+ LogDebug("Failed to add certificates chain");
+ m_connection->RollbackTransaction();
+ return false;
+ }
+
+ }
+ m_connection->CommitTransaction();
+ return true;
}
void SqlQuery::remove_app_from_check_list(const app_t &app)
@@ -265,12 +309,11 @@ void SqlQuery::get_apps(std::list<app_t> &apps_buffer)
while (getAppsCommand->Step()) {
app_t app;
- app.check_id = getAppsCommand->GetColumnInt32(0);
- app.app_id = getAppsCommand->GetColumnString(1);
- app.pkg_id = getAppsCommand->GetColumnString(2);
- app.uid = getAppsCommand->GetColumnInt64(3);
- app.verified = static_cast<app_t::verified_t>(getAppsCommand->GetColumnInt32(4));
- app.certificates = {};
+ app.app_id = getAppsCommand->GetColumnString(0);
+ app.pkg_id = getAppsCommand->GetColumnString(1);
+ app.uid = getAppsCommand->GetColumnInt64(2);
+ app.verified = static_cast<app_t::verified_t>(getAppsCommand->GetColumnInt32(3));
+ app.signatures = {};
LogDebug("App read from DB: app_id: " << app.str() << ", verified: " << static_cast<int32_t>(app.verified));
apps_buffer.push_back(app);
}
@@ -278,18 +321,37 @@ void SqlQuery::get_apps(std::list<app_t> &apps_buffer)
void SqlQuery::get_app_list(std::list<app_t> &apps_buffer)
{
+ m_connection->BeginTransaction();
get_apps(apps_buffer);
- // Get certificates for apps
- for (auto &iter : apps_buffer) {
- SqlConnection::DataCommandAutoPtr getCertsCommand =
- m_connection->PrepareDataCommand(DB_CMD_GET_CERTS);
- getCertsCommand->BindInt32(107, iter.check_id);
-
- while (getCertsCommand->Step()) {
- iter.certificates.push_back(getCertsCommand->GetColumnString(0));
+ // Get chain for every application
+ for (auto &iter_app : apps_buffer) {
+ SqlConnection::DataCommandAutoPtr getChainsCommand =
+ m_connection->PrepareDataCommand(DB_CMD_GET_CHAINS);
+ getChainsCommand->BindString(104, iter_app.app_id.c_str());
+ getChainsCommand->BindString(105, iter_app.pkg_id.c_str());
+ getChainsCommand->BindInt32(106, iter_app.uid);
+
+ // Get all certs from chain
+ while (getChainsCommand->Step()) {
+ chain_t chain;
+ int32_t chain_id;
+ chain_id = getChainsCommand->GetColumnInt32(0);
+ LogDebug("Found chain (" << chain_id << ") for " << iter_app.str());
+
+ SqlConnection::DataCommandAutoPtr getCertsCommand =
+ m_connection->PrepareDataCommand(DB_CMD_GET_CERTS);
+ getCertsCommand->BindInt32(110, chain_id);
+
+ // Add found certs to chain
+ while (getCertsCommand->Step()) {
+ chain.push_back(getCertsCommand->GetColumnString(0));
+ LogDebug("Found certificate (" << chain.size() << ") in chain no. " << chain_id);
+ }
+ iter_app.signatures.push_back(chain);
}
}
+ m_connection->CommitTransaction();
}
} // DB
diff --git a/src/include/cchecker/app.h b/src/include/cchecker/app.h
index 3217bdb..46fd9b6 100644
--- a/src/include/cchecker/app.h
+++ b/src/include/cchecker/app.h
@@ -23,7 +23,6 @@
#define CCHECKER_APP_H
#include <string>
-#include <vector>
#include <list>
#include <sys/types.h>
@@ -33,6 +32,9 @@ namespace CCHECKER {
// Currently in signals from pkgmgr only information about pkg_id is included
const char *const TEMP_APP_ID = "temp#app_id";
+typedef std::list<std::string> chain_t;
+typedef std::list<chain_t> signatures_t;
+
struct app_t {
enum class verified_t : int32_t {
NO = 0,
@@ -40,19 +42,19 @@ struct app_t {
UNKNOWN = 2
};
- int32_t check_id;
- std::string app_id;
- std::string pkg_id;
- uid_t uid;
- std::vector<std::string> certificates; //TODO: add typedef
- verified_t verified;
+ std::string app_id;
+ std::string pkg_id;
+ uid_t uid;
+ signatures_t signatures;
+ verified_t verified;
app_t(void);
app_t(const std::string &app_id,
const std::string &pkg_id,
uid_t uid,
- const std::vector<std::string> &certificates);
+ const signatures_t &signatures);
std::string str(void) const;
+ std::string str_certs(void) const;
};
struct url_t {
diff --git a/src/include/cchecker/sql_query.h b/src/include/cchecker/sql_query.h
index 5a22740..e4cc582 100644
--- a/src/include/cchecker/sql_query.h
+++ b/src/include/cchecker/sql_query.h
@@ -69,6 +69,7 @@ class SqlQuery {
void get_apps(std::list<app_t> &apps_buffer);
bool check_if_app_exists(const app_t &app);
bool get_check_id(const app_t &app, int32_t &check_id);
+ bool add_chain_id(const int32_t check_id, int32_t &chain_id);
int verified_enum_to_int(const app_t::verified_t &verified);
app_t::verified_t verified_int_to_enum(const int &verified);
};
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index a1c88db..bff89b6 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -23,6 +23,8 @@ SET(CERT_CHECKER_TESTS_SOURCES
${CERT_CHECKER_TESTS_SRC_PATH}/main.cpp
${CERT_CHECKER_TESTS_SRC_PATH}/dbfixture.cpp
${CERT_CHECKER_TESTS_SRC_PATH}/colour_log_formatter.cpp
+ ${CERT_CHECKER_TESTS_SRC_PATH}/app_event_operators.cpp
+ ${CERT_CHECKER_TESTS_SRC_PATH}/test_app.cpp
${CERT_CHECKER_TESTS_SRC_PATH}/test_db.cpp
${CERT_CHECKER_TESTS_SRC_PATH}/test_queue.cpp
${CERT_CHECKER_TESTS_SRC_PATH}/queue_test_thread.cpp
diff --git a/tests/app_event_operators.cpp b/tests/app_event_operators.cpp
new file mode 100644
index 0000000..1d26d60
--- /dev/null
+++ b/tests/app_event_operators.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file app_test_class.cpp
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ * @brief Implementation of app_test class (from app_t)
+ */
+
+#include <cchecker/log.h>
+#include <app_event_operators.h>
+
+//using namespace CCHECKER;
+
+namespace CCHECKER {
+
+void sort(app_t &app)
+{
+ for (auto &iter : app.signatures) {
+ iter.sort();
+ }
+ app.signatures.sort();
+}
+
+// Needed for sort()
+bool operator < (const app_t &app1, const app_t &app2)
+{
+ if (app1.app_id != app2.app_id)
+ return app1.app_id < app2.app_id;
+ if (app1.pkg_id != app2.pkg_id)
+ return app1.pkg_id < app2.pkg_id;
+ if (app1.uid != app2.uid)
+ return app1.uid < app2.uid;
+
+ return app1.signatures < app2.signatures;
+}
+
+bool operator ==(const app_t &app1, const app_t &app2)
+{
+ if (app1.app_id != app2.app_id ||
+ app1.pkg_id != app2.pkg_id ||
+ app1.uid != app2.uid ||
+ app1.signatures.size() != app2.signatures.size() ||
+ app1.verified != app2.verified) {
+ LogDebug("app_t compare error: " << app1.str() << " is different than: " << app2.str());
+ return false;
+ }
+
+ return app1.signatures == app2.signatures;
+}
+
+bool operator !=(const app_t &app1, const app_t &app2)
+{
+ return !(app1 == app2);
+}
+
+bool operator ==(const event_t &event1, const event_t &event2)
+{
+ if (event1.event_type != event2.event_type)
+ return false;
+
+ if (event1.app != event2.app)
+ return false;
+
+ return true;
+}
+
+bool operator !=(const event_t &event1, const event_t &event2)
+{
+ return !(event1 == event2);
+}
+
+} // CHCHECKER
diff --git a/tests/app_event_operators.h b/tests/app_event_operators.h
new file mode 100644
index 0000000..3e96d28
--- /dev/null
+++ b/tests/app_event_operators.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file app_test_class.h
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ * @brief Implementation of app_test class (from app_t)
+ */
+
+#include <cchecker/app.h>
+#include <cchecker/queue.h>
+
+#ifndef CCHECKER_APP_TEST_CLASS_H
+#define CCHECKER_APP_TEST_CLASS_H
+
+namespace CCHECKER {
+
+void sort(app_t &app);
+bool operator ==(const app_t &app1, const app_t &app2);
+bool operator !=(const app_t &app1, const app_t &app2);
+bool operator < (const app_t &app1, const app_t &app2);
+
+bool operator ==(const event_t &event1, const event_t &event2);
+bool operator !=(const event_t &event1, const event_t &event2);
+
+} // CCHECKER
+
+#endif //CCHECKER_APP_TEST_CLASS_H
diff --git a/tests/test_app.cpp b/tests/test_app.cpp
new file mode 100644
index 0000000..20bf905
--- /dev/null
+++ b/tests/test_app.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @file test_app.cpp
+ * @author Janusz Kozerski (j.kozerski@samsung.com)
+ * @version 1.0
+ * @brief App structure tests
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <string>
+
+#include <cchecker/log.h>
+#include <app_event_operators.h>
+
+using namespace CCHECKER;
+
+BOOST_FIXTURE_TEST_SUITE(APP_TEST, app_t)
+
+BOOST_AUTO_TEST_CASE(App_positive) {
+
+ app_t app1("app_1", "pkg_1", 5001, {{"aaaaaa"}});
+ app_t app2("app_1", "pkg_1", 5001, {{"aaaaaa"}});
+
+ app_t app3("app_2", "pkg_1", 5002, {{"aaa", "bbbb"}});
+ app_t app4("app_2", "pkg_1", 5002, {{"bbbb", "aaa"}});
+
+ chain_t chain411 = {"cert_4.1", "cert 4.2"};
+ chain_t chain412 = {"cert 4.2", "cert_4.1"};
+ chain_t chain421 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"};
+ chain_t chain422 = {"cert 4.2.2", "cert 4.2.3", "cert_4.2.1"};
+ chain_t chain423 = {"cert 4.2.3", "cert_4.2.1", "cert 4.2.2"};
+ chain_t chain424 = {"cert_4.2.1", "cert 4.2.3", "cert 4.2.2"};
+ chain_t chain425 = {"cert 4.2.3", "cert 4.2.2", "cert_4.2.1"};
+ chain_t chain426 = {"cert 4.2.2", "cert_4.2.1", "cert 4.2.3"};
+ chain_t chain43 = {"cert_4.3.1"};
+
+ app_t app5("app_3", "pkg_1", 5003, {chain411, chain421, chain43});
+ app_t app6("app_3", "pkg_1", 5003, {chain411, chain422, chain43});
+ app_t app7("app_3", "pkg_1", 5003, {chain411, chain423, chain43});
+ app_t app8("app_3", "pkg_1", 5003, {chain411, chain424, chain43});
+ app_t app9("app_3", "pkg_1", 5003, {chain411, chain425, chain43});
+ app_t app10("app_3", "pkg_1", 5003, {chain411, chain426, chain43});
+ app_t app11("app_3", "pkg_1", 5003, {chain412, chain421, chain43});
+ app_t app12("app_3", "pkg_1", 5003, {chain412, chain422, chain43});
+ app_t app13("app_3", "pkg_1", 5003, {chain412, chain423, chain43});
+ app_t app14("app_3", "pkg_1", 5003, {chain412, chain424, chain43});
+ app_t app15("app_3", "pkg_1", 5003, {chain412, chain425, chain43});
+ app_t app16("app_3", "pkg_1", 5003, {chain412, chain426, chain43});
+
+ sort(app1);
+ sort(app2);
+ sort(app3);
+ sort(app4);
+ sort(app5);
+ sort(app6);
+ sort(app7);
+ sort(app8);
+ sort(app9);
+ sort(app10);
+ sort(app11);
+ sort(app12);
+ sort(app13);
+ sort(app14);
+ sort(app15);
+ sort(app16);
+
+ BOOST_REQUIRE(app1 == app2);
+
+ BOOST_REQUIRE(app3 == app4);
+
+ BOOST_REQUIRE(app5 == app6);
+ BOOST_REQUIRE(app6 == app7);
+ BOOST_REQUIRE(app7 == app8);
+ BOOST_REQUIRE(app8 == app9);
+ BOOST_REQUIRE(app9 == app10);
+ BOOST_REQUIRE(app10 == app11);
+ BOOST_REQUIRE(app11 == app12);
+ BOOST_REQUIRE(app12 == app13);
+ BOOST_REQUIRE(app13 == app14);
+ BOOST_REQUIRE(app14 == app15);
+ BOOST_REQUIRE(app15 == app16);
+ BOOST_REQUIRE(app16 == app5);
+}
+
+BOOST_AUTO_TEST_CASE(App_negative) {
+
+ app_t app1("app_1", "pkg_1", 5001, {{"aaaaaa"}});
+ app_t app2("app_2", "pkg_1", 5001, {{"aaaaaa"}});
+ app_t app3("app_2", "pkg_2", 5001, {{"aaaaaa"}});
+ app_t app4("app_2", "pkg_2", 5002, {{"aaaaaa"}});
+
+ chain_t chain411 = {"cert_4.1", "cert 4.2"};
+ chain_t chain412 = {"cert_4.1"};
+
+ chain_t chain421 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"};
+ chain_t chain422 = {"" "cert 4.2.3", "cert_4.2.1"};
+ chain_t chain423 = {"cert", "cert_4.2.1", "cert 4.2.2"};
+ chain_t chain424 = {"cert_4.2.1", " ", "cert 4.2.2"};
+ chain_t chain425 = {"cert 4.2.3", "cert 4.2.2"};
+ chain_t chain426 = {"cert 4.2", "cert_4.2", "cert 4.2"};
+
+ chain_t chain43 = {"cert_4.3.1"};
+
+ app_t app5("app_3", "pkg_1", 5003, {chain411, chain421, chain43});
+ app_t app6("app_3", "pkg_1", 5003, {chain411, chain422, chain43});
+ app_t app7("app_3", "pkg_1", 5003, {chain411, chain423, chain43});
+ app_t app8("app_3", "pkg_1", 5003, {chain411, chain424, chain43});
+ app_t app9("app_3", "pkg_1", 5003, {chain411, chain425, chain43});
+ app_t app10("app_3", "pkg_1", 5003, {chain411, chain426, chain43});
+ app_t app11("app_3", "pkg_1", 5003, {chain412, chain421, chain43});
+ app_t app12("app_3", "pkg_1", 5003, {chain412, chain422, chain43});
+ app_t app13("app_3", "pkg_1", 5003, {chain412, chain423, chain43});
+ app_t app14("app_3", "pkg_1", 5003, {chain412, chain424, chain43});
+ app_t app15("app_3", "pkg_1", 5003, {chain412, chain425, chain43});
+ app_t app16("app_3", "pkg_1", 5003, {chain412, chain426, chain43});
+
+ app_t apps[12] = {app5, app6, app7, app8, app9, app10, app11, app12, app13, app14, app15, app16};
+
+ sort(app1);
+ sort(app2);
+ sort(app3);
+ sort(app4);
+
+ for (int i=0; i<12; i++) {
+ sort(apps[i]);
+ }
+
+ BOOST_REQUIRE(app1 != app2);
+ BOOST_REQUIRE(app1 != app3);
+ BOOST_REQUIRE(app1 != app4);
+ BOOST_REQUIRE(app2 != app3);
+ BOOST_REQUIRE(app2 != app4);
+ BOOST_REQUIRE(app3 != app4);
+
+ for (int i=0; i<12; i++) {
+ for (int j=0; j<12; j++) {
+ if (i != j)
+ BOOST_REQUIRE(apps[i] != apps[j]);
+ else
+ BOOST_REQUIRE(apps[i] == apps[j]);
+ }
+ }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/test_db.cpp b/tests/test_db.cpp
index dd5a962..e9685a8 100644
--- a/tests/test_db.cpp
+++ b/tests/test_db.cpp
@@ -24,9 +24,9 @@
#include <boost/test/unit_test.hpp>
#include <string>
-#include <cchecker/app.h>
#include <cchecker/log.h>
#include <dbfixture.h>
+#include <app_event_operators.h>
BOOST_FIXTURE_TEST_SUITE(DB_TEST, DBFixture)
@@ -96,15 +96,27 @@ BOOST_AUTO_TEST_CASE(DB_url) {
BOOST_REQUIRE(url==url_org2);
}
-BOOST_AUTO_TEST_CASE(DB_app) {
+BOOST_AUTO_TEST_CASE(DB_app_positive) {
clear_database();
std::list<app_t> buffer;
app_t app1("app_1", "pkg_1", 5001, {});
- app_t app2("app_2", "pkg 2", 5002, {"cert_2"});
- app_t app2r("app_2_remove", "pkg 2", 5002, {"cert_2"});
- app_t app3("app 3", "pkg 3", 5003, {"cert_3.1", "cert 3.2"});
- app_t app4("app 4", "pkg 4", 5004, {"cert_4.1", "cert 4.2", "cert 4.3"});
+
+ chain_t chain2 = {"cert2"};
+ app_t app2("app_2", "pkg 2", 5002, {chain2});
+
+ chain_t chain2r = {"cert2r"};
+ app_t app2r("app_2_remove", "pkg 2", 5002, {chain2, chain2r});
+
+ chain_t chain31 = {"cert_3.1", "cert 3.2"};
+ chain_t chain32 = {"cert_3.1"};
+ app_t app3("app 3", "pkg 3", 5003, {chain31, chain32});
+
+ chain_t chain41 = {"cert_4.1", "cert 4.2"};
+ chain_t chain42 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"};
+ chain_t chain43 = {"cert_4.3.1"};
+
+ app_t app4("app 4", "pkg 4", 5004, {chain41, chain42, chain43});
BOOST_REQUIRE(add_app_to_check_list(app1)==true);
BOOST_REQUIRE(add_app_to_check_list(app2)==true);
@@ -118,29 +130,65 @@ BOOST_AUTO_TEST_CASE(DB_app) {
app2.verified = app_t::verified_t::NO;
app3.verified = app_t::verified_t::YES;
+ sort(app1);
+ sort(app2);
+ sort(app3);
+ sort(app4);
+ std::list<app_t> buffer_ok = {app1, app2, app3, app4};
+
+ get_app_list(buffer);
+
+ buffer.sort();
+ buffer_ok.sort();
+ BOOST_REQUIRE(buffer_ok == buffer);
+}
+
+BOOST_AUTO_TEST_CASE(DB_app_negative) {
+ clear_database();
+
+ std::list<app_t> buffer;
+ app_t app1("app_1", "pkg_1", 5001, {});
+
+ chain_t chain2 = {"cert2"};
+ app_t app2("app_2", "pkg 2", 5002, {chain2});
+
+ chain_t chain2r = {"cert2r"};
+ app_t app2r("app_2_remove", "pkg 2", 5002, {chain2, chain2r});
+
+ chain_t chain31 = {"cert_3.1", "cert 3.2"};
+ chain_t chain32 = {"cert_3.1"};
+ app_t app3("app 3", "pkg 3", 5003, {chain31, chain32});
+
+ chain_t chain41 = {"cert_4.1", "cert 4.2"};
+ chain_t chain42 = {"cert_4.2.1", "cert 4.2.2", "cert 4.2.3"};
+ chain_t chain43 = {"cert_4.3.1"};
+
+ app_t app4("app 4", "pkg 4", 5004, {chain41, chain42, chain43});
+
+ BOOST_REQUIRE(add_app_to_check_list(app1)==true);
+ BOOST_REQUIRE(add_app_to_check_list(app2)==true);
+ BOOST_REQUIRE(add_app_to_check_list(app2r)==true);
+ // Skipp adding app3 to database
+ BOOST_REQUIRE(add_app_to_check_list(app4)==true);
+
+ mark_as_verified(app2, app_t::verified_t::NO);
+ mark_as_verified(app3, app_t::verified_t::YES);
+ remove_app_from_check_list(app2r);
+
+ app2.verified = app_t::verified_t::NO;
+ app3.verified = app_t::verified_t::YES;
+ sort(app1);
+ sort(app2);
+ sort(app3);
+ sort(app4);
std::list<app_t> buffer_ok = {app1, app2, app3, app4};
get_app_list(buffer);
- std::list<app_t>::iterator iter = buffer.begin();
- std::list<app_t>::iterator iter_ok = buffer_ok.begin();
- for (; iter!=buffer.end(); iter++) {
- bool is_ok = false;
- for (iter_ok = buffer_ok.begin(); iter_ok!=buffer_ok.end(); iter_ok++) {
- if (iter->app_id == iter_ok->app_id &&
- iter->pkg_id == iter_ok->pkg_id &&
- iter->uid == iter_ok->uid &&
- iter->certificates == iter_ok->certificates &&
- iter->verified == iter_ok->verified) {
- // check_id field is created by database and can be ignored
- LogDebug(iter->str() << " has been found");
- is_ok = true;
- buffer_ok.erase(iter_ok);
- break;
- }
- }
- BOOST_REQUIRE(is_ok == true);
- }
+ // list has to be sorted before comparison.
+ buffer.sort();
+ buffer_ok.sort();
+ BOOST_REQUIRE(buffer_ok != buffer);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/test_queue.cpp b/tests/test_queue.cpp
index 2fe7f3e..384d6e4 100644
--- a/tests/test_queue.cpp
+++ b/tests/test_queue.cpp
@@ -24,16 +24,28 @@
#include <string>
#include <thread>
-#include <cchecker/app.h>
#include <cchecker/log.h>
-#include <cchecker/queue.h>
-
#include <queue_test_thread.h>
+#include <app_event_operators.h>
using namespace CCHECKER;
BOOST_FIXTURE_TEST_SUITE(QUEUE_TEST, Queue)
+BOOST_AUTO_TEST_CASE(Queue_operators) {
+ app_t app1("app_id1", "pkg_id1", 1, {});
+ app_t app2("app_id2", "pkg_id2", 2, {});
+ app_t app3("app_id@", "###", 3, {});
+
+ event_t ev1(app1, event_t::event_type_t::APP_INSTALL);
+ event_t ev2(app1, event_t::event_type_t::APP_UNINSTALL);
+
+ BOOST_REQUIRE(ev1 == ev1);
+ BOOST_REQUIRE(ev1 != ev2);
+ BOOST_REQUIRE(ev2 != ev1);
+ BOOST_REQUIRE(ev2 == ev2);
+}
+
BOOST_AUTO_TEST_CASE(Queue) {
app_t app1("app_id1", "pkg_id1", 1, {});
@@ -55,12 +67,8 @@ BOOST_AUTO_TEST_CASE(Queue) {
BOOST_REQUIRE(empty() == false);
BOOST_REQUIRE(pop_event(ev) == true);
- BOOST_REQUIRE(ev1.app.app_id == ev.app.app_id);
- BOOST_REQUIRE(ev1.app.pkg_id == ev.app.pkg_id);
- BOOST_REQUIRE(ev1.app.uid == ev.app.uid);
- // Certs and verified flag aren't used in queue, but can be tested
- BOOST_REQUIRE(ev1.app.certificates == ev.app.certificates);
- BOOST_REQUIRE(ev1.app.verified == ev.app.verified);
+ BOOST_REQUIRE(ev1 == ev);
+
BOOST_REQUIRE(empty() == true);
push_event(ev2);
@@ -68,21 +76,11 @@ BOOST_AUTO_TEST_CASE(Queue) {
BOOST_REQUIRE(empty() == false);
BOOST_REQUIRE(pop_event(ev) == true);
- BOOST_REQUIRE(ev2.app.app_id == ev.app.app_id);
- BOOST_REQUIRE(ev2.app.pkg_id == ev.app.pkg_id);
- BOOST_REQUIRE(ev2.app.uid == ev.app.uid);
- // Certs and verified flag aren't used in queue, but can be tested
- BOOST_REQUIRE(ev2.app.certificates == ev.app.certificates);
- BOOST_REQUIRE(ev2.app.verified == ev.app.verified);
-
+ BOOST_REQUIRE(ev2 == ev);
BOOST_REQUIRE(pop_event(ev) == true);
- BOOST_REQUIRE(ev3.app.app_id == ev.app.app_id);
- BOOST_REQUIRE(ev3.app.pkg_id == ev.app.pkg_id);
- BOOST_REQUIRE(ev3.app.uid == ev.app.uid);
- // Certs and verified flag aren't used in queue, but can be tested
- BOOST_REQUIRE(ev3.app.certificates == ev.app.certificates);
- BOOST_REQUIRE(ev3.app.verified == ev.app.verified);
+ BOOST_REQUIRE(ev3 == ev);
+
BOOST_REQUIRE(empty() == true);
BOOST_REQUIRE(pop_event(ev) == false);
@@ -96,12 +94,8 @@ BOOST_AUTO_TEST_CASE(Queue) {
push_event(ev4);
BOOST_REQUIRE(pop_event(ev) == true);
- BOOST_REQUIRE(ev4.app.app_id == ev.app.app_id);
- BOOST_REQUIRE(ev4.app.pkg_id == ev.app.pkg_id);
- BOOST_REQUIRE(ev4.app.uid == ev.app.uid);
- // Certs and verified flag aren't used in queue, but can be tested
- BOOST_REQUIRE(ev4.app.certificates == ev.app.certificates);
- BOOST_REQUIRE(ev4.app.verified == ev.app.verified);
+ BOOST_REQUIRE(ev4 == ev);
+
BOOST_REQUIRE(pop_event(ev) == false);
BOOST_REQUIRE(empty() == true);