summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);