From 8a9adaa9c38a3269942181abadb5f700b7661ccb Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Thu, 26 Feb 2015 14:39:39 +0100
Subject: [PATCH 01/16] Fix basename() usage in ChecksumGenerator
Contents of a string passed to basename() as an argument may be modified
(it depends on implementation). In order not to perform unexpected
changes, duplicate of given string is passed to basename().
Change-Id: Ib783629160f9528a6054dd0f78b9ebd5e6870fb6
---
src/chsgen/ChecksumGenerator.cpp | 32 +++++++++++++++++++++++---------
src/chsgen/ChecksumGenerator.h | 4 ++--
2 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/chsgen/ChecksumGenerator.cpp b/src/chsgen/ChecksumGenerator.cpp
index 6255403..fcc76dc 100644
--- a/src/chsgen/ChecksumGenerator.cpp
+++ b/src/chsgen/ChecksumGenerator.cpp
@@ -23,6 +23,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -43,8 +45,10 @@ const char ChecksumGenerator::m_fieldSeparator(StorageConfig::fieldSeparator);
const char ChecksumGenerator::m_recordSeparator(StorageConfig::recordSeparator);
const std::string ChecksumGenerator::m_backupFilenameSuffix(StorageConfig::backupFilenameSuffix);
-ChecksumGenerator::ChecksumGenerator(int argc, char * const *argv) : m_copyStream(std::string()) {
- m_filename = (1 < argc ? argv[1] : std::string());
+ChecksumGenerator::ChecksumGenerator(int argc, char * const *argv) {
+ if (argc > 1) {
+ m_pathname = argv[1];
+ }
}
int ChecksumGenerator::run(void) {
@@ -65,11 +69,14 @@ int ChecksumGenerator::run(void) {
} catch (const std::length_error &ex) {
std::cerr << ex.what() << std::endl;
return CYNARA_API_UNKNOWN_ERROR;
+ } catch (const std::bad_alloc &ex) {
+ std::cerr << ex.what() << std::endl;
+ return CYNARA_API_OUT_OF_MEMORY;
}
}
const std::string ChecksumGenerator::generate(const std::string &data) {
- auto checksum = crypt(data.c_str(), "$1$");
+ const char *checksum = crypt(data.c_str(), "$1$");
if (nullptr != checksum) {
return std::string(checksum);
@@ -85,10 +92,10 @@ const std::string ChecksumGenerator::generate(const std::string &data) {
};
void ChecksumGenerator::openFileStream(void) {
- m_inputStream.open(m_filename);
+ m_inputStream.open(m_pathname);
if (!m_inputStream.is_open()) {
- throw FileNotFoundException(m_filename);
+ throw FileNotFoundException(m_pathname);
}
}
@@ -100,14 +107,21 @@ void ChecksumGenerator::copyFileStream(void) {
}
void ChecksumGenerator::printRecord(void) const {
- std::string filename(basename(m_filename.c_str()));
- getBasicFilename(filename);
+ std::unique_ptr pathnameDuplicate(strdup(m_pathname.c_str()), free);
+ if (pathnameDuplicate == nullptr) {
+ LOGE("Insufficient memory available to allocate duplicate filename: <%s>",
+ m_pathname.c_str());
+ throw std::bad_alloc();
+ }
+
+ std::string basename(::basename(pathnameDuplicate.get()));
+ removeBackupSuffix(basename);
- std::cout << filename << m_fieldSeparator << generate(m_copyStream.str())
+ std::cout << basename << m_fieldSeparator << generate(m_copyStream.str())
<< m_recordSeparator;
}
-void ChecksumGenerator::getBasicFilename(std::string &filename) const {
+void ChecksumGenerator::removeBackupSuffix(std::string &filename) const {
auto backupSuffixPos = filename.rfind(m_backupFilenameSuffix);
if (std::string::npos != backupSuffixPos &&
diff --git a/src/chsgen/ChecksumGenerator.h b/src/chsgen/ChecksumGenerator.h
index a3e96e0..30e34fb 100644
--- a/src/chsgen/ChecksumGenerator.h
+++ b/src/chsgen/ChecksumGenerator.h
@@ -42,11 +42,11 @@ private:
void openFileStream(void);
void copyFileStream(void);
void printRecord(void) const;
- void getBasicFilename(std::string &filename) const;
+ void removeBackupSuffix(std::string &filename) const;
std::ifstream m_inputStream;
std::stringstream m_copyStream;
- std::string m_filename;
+ std::string m_pathname;
static const char m_fieldSeparator;
static const char m_recordSeparator;
static const std::string m_backupFilenameSuffix;
--
2.7.4
From 7832866a7fbf8b6425e180d1dbdfe7b80ab8f96d Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Tue, 23 Dec 2014 14:53:59 +0100
Subject: [PATCH 02/16] Introduce ChecksumValidator
ChecksumValidator computes checksums for every file listed in checksum
index equivalent using crypt(3). As a result, base64-like (custom
alphabet) encoded strings are produced and compared with last known
corresponding digest. Its 4-character prefix indicates used algorithm.
Class will be later used as an integrity mechanism extension.
Change-Id: Ibaba636bae30c747e8eac5561e9b130d4398518e
---
src/storage/CMakeLists.txt | 2 +
src/storage/ChecksumValidator.cpp | 142 ++++++++++++++++++++++++++++++++++++++
src/storage/ChecksumValidator.h | 65 +++++++++++++++++
test/CMakeLists.txt | 1 +
4 files changed, 210 insertions(+)
create mode 100644 src/storage/ChecksumValidator.cpp
create mode 100644 src/storage/ChecksumValidator.h
diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt
index 7bccc8c..996b37a 100644
--- a/src/storage/CMakeLists.txt
+++ b/src/storage/CMakeLists.txt
@@ -24,6 +24,7 @@ SET(CYNARA_LIB_CYNARA_STORAGE_PATH ${CYNARA_PATH}/storage)
SET(LIB_CYNARA_STORAGE_SOURCES
${CYNARA_LIB_CYNARA_STORAGE_PATH}/BucketDeserializer.cpp
+ ${CYNARA_LIB_CYNARA_STORAGE_PATH}/ChecksumValidator.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/InMemoryStorageBackend.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/Integrity.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/Storage.cpp
@@ -51,6 +52,7 @@ SET_TARGET_PROPERTIES(
TARGET_LINK_LIBRARIES(${TARGET_LIB_CYNARA_STORAGE}
${CYNARA_DEP_LIBRARIES}
${TARGET_CYNARA_COMMON}
+ crypt
)
INSTALL(TARGETS ${TARGET_LIB_CYNARA_STORAGE} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/src/storage/ChecksumValidator.cpp b/src/storage/ChecksumValidator.cpp
new file mode 100644
index 0000000..1354ad1
--- /dev/null
+++ b/src/storage/ChecksumValidator.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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 src/storage/ChecksumValidator.cpp
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief This file contains ChecksumValidator implementation.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "ChecksumValidator.h"
+
+namespace Cynara {
+
+const std::string ChecksumValidator::m_checksumFilename(PathConfig::StoragePath::checksumFilename);
+const std::string ChecksumValidator::m_backupFilenameSuffix(
+ PathConfig::StoragePath::backupFilenameSuffix);
+
+void ChecksumValidator::load(std::istream &stream) {
+ m_sums.clear();
+
+ std::string line;
+ std::size_t lineNum = 1;
+ while (std::getline(stream, line, PathConfig::StoragePath::recordSeparator)) {
+ try {
+ std::size_t beginToken = 0;
+ std::string filename = parseFilename(line, beginToken);
+ std::string checksum = parseChecksum(line, beginToken);
+
+ m_sums.insert({ filename, checksum });
+ ++lineNum;
+ } catch (const ChecksumRecordCorruptedException &ex) {
+ throw ex.withLineNumber(lineNum);
+ }
+ }
+};
+
+const std::string ChecksumValidator::generate(const std::string &data) {
+ const char *checksum = crypt(data.c_str(), "$1$");
+
+ if (nullptr != checksum) {
+ return checksum;
+ }
+
+ int err = errno;
+ if (err == ENOSYS) {
+ LOGE("'crypt' function was not implemented; error [%d] : <%s>", err, strerror(err));
+ } else {
+ LOGE("'crypt' function error [%d] : <%s>", err, strerror(err));
+ }
+ throw UnexpectedErrorException(err, strerror(err));
+};
+
+void ChecksumValidator::compare(std::istream &stream, const std::string &pathname,
+ bool isBackupValid) {
+ if (isChecksumIndex(pathname)) {
+ return;
+ }
+
+ std::unique_ptr pathnameDuplicate(strdup(pathname.c_str()), free);
+ if (pathnameDuplicate == nullptr) {
+ LOGE("Insufficient memory available to allocate duplicate filename: <%s>",
+ pathname.c_str());
+ throw std::bad_alloc();
+ }
+
+ std::string filename(::basename(pathnameDuplicate.get()));
+ std::stringstream copyStream;
+
+ if (isBackupValid) {
+ auto backupSuffixPos = filename.rfind(m_backupFilenameSuffix);
+
+ if ((std::string::npos != backupSuffixPos) &&
+ (filename.size() == (backupSuffixPos + m_backupFilenameSuffix.size()))) {
+ filename.erase(backupSuffixPos);
+ }
+ }
+
+ std::copy(std::istreambuf_iterator(stream),
+ std::istreambuf_iterator(),
+ std::ostreambuf_iterator(copyStream));
+ stream.seekg(0);
+
+ if (m_sums[filename] != generate(copyStream.str())) {
+ throw ChecksumRecordCorruptedException(m_sums[filename]);
+ }
+};
+
+const std::string ChecksumValidator::parseFilename(const std::string &line,
+ std::size_t &beginToken) {
+ std::size_t filenameEndToken = line.find(PathConfig::StoragePath::fieldSeparator, beginToken);
+ if (filenameEndToken != beginToken && filenameEndToken != std::string::npos) {
+ auto filename = line.substr(beginToken, filenameEndToken - beginToken);
+ beginToken = filenameEndToken + 1;
+ return filename;
+ }
+ throw ChecksumRecordCorruptedException(line);
+}
+
+const std::string ChecksumValidator::parseChecksum(const std::string &line,
+ std::size_t &beginToken) {
+ if (beginToken >= line.size()) {
+ throw ChecksumRecordCorruptedException(line);
+ }
+
+ auto checksum = line.substr(beginToken);
+ beginToken = line.size();
+ return checksum;
+}
+
+bool ChecksumValidator::isChecksumIndex(const std::string &filename) const {
+ auto checksum = m_dbPath + m_checksumFilename;
+ return (filename == checksum || filename == checksum + m_backupFilenameSuffix);
+}
+
+} // namespace Cynara
diff --git a/src/storage/ChecksumValidator.h b/src/storage/ChecksumValidator.h
new file mode 100644
index 0000000..bfd577b
--- /dev/null
+++ b/src/storage/ChecksumValidator.h
@@ -0,0 +1,65 @@
+/*
+ * 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 src/storage/ChecksumValidator.h
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief This file contains ChecksumValidator header.
+ */
+
+#ifndef SRC_STORAGE_CHECKSUMVALIDATOR_H_
+#define SRC_STORAGE_CHECKSUMVALIDATOR_H_
+
+#include
+#include
+#include
+#include
+
+namespace Cynara {
+
+class ChecksumValidator;
+typedef std::unique_ptr ChecksumValidatorUniquePtr;
+
+class ChecksumValidator {
+public:
+ ChecksumValidator(const std::string &path) : m_dbPath(path) {}
+
+ void load(std::istream &stream);
+ void compare(std::istream &stream, const std::string &pathname, bool isBackupValid);
+
+ void clear(void) {
+ m_sums.clear();
+ }
+
+ static const std::string generate(const std::string &data);
+
+protected:
+ typedef std::unordered_map Checksums;
+
+ bool isChecksumIndex(const std::string &pathname) const;
+
+ static const std::string parseFilename(const std::string &line, std::size_t &beginToken);
+ static const std::string parseChecksum(const std::string &line, std::size_t &beginToken);
+
+ Checksums m_sums;
+ const std::string m_dbPath;
+ static const std::string m_checksumFilename;
+ static const std::string m_backupFilenameSuffix;
+};
+
+} // namespace Cynara
+
+#endif // SRC_STORAGE_CHECKSUMVALIDATOR_H_
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d937d3c..f9b42a8 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -63,6 +63,7 @@ SET(CYNARA_SOURCES_FOR_TESTS
${CYNARA_SRC}/helpers/creds-commons/creds-commons.cpp
${CYNARA_SRC}/service/main/CmdlineParser.cpp
${CYNARA_SRC}/storage/BucketDeserializer.cpp
+ ${CYNARA_SRC}/storage/ChecksumValidator.cpp
${CYNARA_SRC}/storage/InMemoryStorageBackend.cpp
${CYNARA_SRC}/storage/Integrity.cpp
${CYNARA_SRC}/storage/Storage.cpp
--
2.7.4
From 9f0e503b603acb3bcb7dfedd6fd27216070e6be7 Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Tue, 27 Jan 2015 11:47:19 +0100
Subject: [PATCH 03/16] Add tests for ChecksumValidator
Add tests checking if ChecksumValidator properly:
* generates checksums,
* loads them or rejects corrupted records,
* supports backup files.
Change-Id: I2e4222283cc0676490134819561824df6661034f
---
test/CMakeLists.txt | 1 +
test/storage/checksum/checksumvalidator.cpp | 154 +++++++++++++++++++++++
test/storage/checksum/checksumvalidatorfixture.h | 54 ++++++++
test/storage/checksum/fakechecksumvalidator.h | 37 ++++++
4 files changed, 246 insertions(+)
create mode 100644 test/storage/checksum/checksumvalidator.cpp
create mode 100644 test/storage/checksum/checksumvalidatorfixture.h
create mode 100644 test/storage/checksum/fakechecksumvalidator.h
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f9b42a8..5050634 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -92,6 +92,7 @@ SET(CYNARA_TESTS_SOURCES
cyad/policy_parser.cpp
helpers.cpp
service/main/cmdlineparser.cpp
+ storage/checksum/checksumvalidator.cpp
storage/performance/bucket.cpp
storage/storage/policies.cpp
storage/storage/check.cpp
diff --git a/test/storage/checksum/checksumvalidator.cpp b/test/storage/checksum/checksumvalidator.cpp
new file mode 100644
index 0000000..19918f3
--- /dev/null
+++ b/test/storage/checksum/checksumvalidator.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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/storage/checksum/checksumvalidator.cpp
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief Tests of ChecksumValidator
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "checksumvalidatorfixture.h"
+#include "fakechecksumvalidator.h"
+
+using namespace Cynara;
+
+const std::string ChecksumValidatorFixture::m_dbPath("/fake/path/");
+const std::string ChecksumValidatorFixture::m_filename("fakeFilename");
+const std::string ChecksumValidatorFixture::m_checksum("$1$$fakeChecksum");
+const std::string ChecksumValidatorFixture::m_backupFilenameSuffix(
+ PathConfig::StoragePath::backupFilenameSuffix);
+const char ChecksumValidatorFixture::m_fieldSeparator(PathConfig::StoragePath::fieldSeparator);
+const char ChecksumValidatorFixture::m_recordSeparator(PathConfig::StoragePath::recordSeparator);
+const size_t ChecksumValidatorFixture::m_firstLine(1);
+
+/**
+ * @brief Verify if generate() can use systems' crypt(3) implementation
+ * @test Expected result: no exceptions are thrown and non-empty string is returned
+ */
+TEST_F(ChecksumValidatorFixture, generateChecksum) {
+ for (const auto &data : { std::string("test-data"), std::string() }) {
+ SCOPED_TRACE(data);
+
+ std::string returnedChecksum;
+ ASSERT_NO_THROW(returnedChecksum = ChecksumValidator::generate(data));
+ ASSERT_NE(std::string(), returnedChecksum);
+ }
+}
+
+/**
+ * @brief Verify if load() can successfully parse sample checksum record
+ * @test Expected result:
+ * - no exceptions are thrown from load()
+ * - proper checksums are stored for corresponding files
+ */
+TEST_F(ChecksumValidatorFixture, parseCorrectRecords) {
+ std::istringstream checksums(m_filename + m_fieldSeparator + m_checksum);
+
+ FakeChecksumValidator validator(m_dbPath);
+ ASSERT_NO_THROW(validator.load(checksums));
+ ASSERT_EQ(m_checksum, validator.sums().at(m_filename));
+}
+
+/**
+ * @brief Verify if load() rejects storing corrupted checksum records
+ * @test Expected result:
+ * - load() throws ChecksumRecordCorruptedException
+ * - no data is stored (there was no correct data to insert)
+ */
+TEST_F(ChecksumValidatorFixture, parseCorruptedRecords) {
+ const auto badLines = { m_filename + m_fieldSeparator,
+ m_filename + m_checksum,
+ m_fieldSeparator + m_checksum };
+
+ FakeChecksumValidator validator(m_dbPath);
+
+ for (const auto &badLine : badLines) {
+ SCOPED_TRACE(badLine);
+ std::istringstream checksums(badLine);
+
+ ASSERT_THROW(validator.load(checksums), ChecksumRecordCorruptedException);
+ ASSERT_TRUE(validator.sums().empty());
+ }
+}
+
+/**
+ * @brief Verify if compare() can successfully check sample database file
+ * @test Expected result: no exceptions are thrown and file contents are still readable
+ */
+TEST_F(ChecksumValidatorFixture, compareBasicAndBackup) {
+ FakeChecksumValidator validator(m_dbPath);
+ std::string checksumsContents;
+ simpleChecksumsContents(checksumsContents);
+
+ std::istringstream checksums(checksumsContents);
+ validator.load(checksums);
+
+ std::unordered_map files = { { "_", std::string() },
+ { "buckets", ";0x0;\n" } };
+
+ for (const auto &file : files) {
+ const auto filename = m_dbPath + file.first;
+ const auto contents = file.second;
+ std::istringstream fakeFile(contents);
+
+ SCOPED_TRACE(filename);
+
+ ASSERT_NO_THROW(validator.compare(fakeFile, filename, false));
+ ASSERT_NO_THROW(validator.compare(fakeFile, filename + m_backupFilenameSuffix, true));
+
+ ASSERT_EQ(contents, fakeFile.str());
+ }
+}
+
+/**
+ * @brief Verify if compare() throws an exception when checksum mismatch is detected
+ * @test Expected result: ChecksumRecordCorruptedException is thrown
+ */
+TEST_F(ChecksumValidatorFixture, checksumMismatch) {
+ FakeChecksumValidator validator(m_dbPath);
+ std::string checksumsContents;
+ simpleChecksumsContents(checksumsContents);
+
+ std::istringstream checksums(checksumsContents);
+ validator.load(checksums);
+
+ // Please note that default policy is set to ALLOW instead of DENY
+ std::unordered_map files = { { "_", "client;user;privilege;0x0;" },
+ { "buckets", ";0xFFFF;\n" } };
+
+ for (const auto &file : files) {
+ const auto filename = m_dbPath + file.first;
+ const auto contents = file.second;
+ std::istringstream fakeFile(contents);
+ SCOPED_TRACE(filename);
+
+ ASSERT_THROW(validator.compare(fakeFile, filename, false),
+ ChecksumRecordCorruptedException);
+ }
+}
diff --git a/test/storage/checksum/checksumvalidatorfixture.h b/test/storage/checksum/checksumvalidatorfixture.h
new file mode 100644
index 0000000..6fb28f6
--- /dev/null
+++ b/test/storage/checksum/checksumvalidatorfixture.h
@@ -0,0 +1,54 @@
+/*
+ * 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/storage/checksum/checksumvalidatorfixture.h
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief Fixture for ChecksumValidator tests
+ */
+
+#ifndef CHECKSUMVALIDATORFIXTURE_H_
+#define CHECKSUMVALIDATORFIXTURE_H_
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+class ChecksumValidatorFixture : public ::testing::Test {
+protected:
+ void simpleChecksumsContents(std::string &contents) {
+ std::stringstream buffer;
+ buffer << "_" << m_fieldSeparator << "$1$$qRPK7m23GJusamGpoGLby/" << m_recordSeparator
+ << "buckets" << m_fieldSeparator << "$1$$6ZlVs5lw2nZgVmiw0BdY21"
+ << m_recordSeparator;
+
+ contents = buffer.str();
+ }
+
+ static const std::string m_dbPath;
+ static const std::string m_filename;
+ static const std::string m_checksum;
+ static const std::string m_backupFilenameSuffix;
+ static const char m_fieldSeparator;
+ static const char m_recordSeparator;
+ static const size_t m_firstLine;
+};
+
+#endif /* CHECKSUMVALIDATORFIXTURE_H_ */
diff --git a/test/storage/checksum/fakechecksumvalidator.h b/test/storage/checksum/fakechecksumvalidator.h
new file mode 100644
index 0000000..af3ed82
--- /dev/null
+++ b/test/storage/checksum/fakechecksumvalidator.h
@@ -0,0 +1,37 @@
+/*
+ * 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/storage/checksum/fakechecksumvalidator.h
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief Mock of ChecksumValidator
+ */
+
+#ifndef FAKECHECKSUMVALIDATOR_H_
+#define FAKECHECKSUMVALIDATOR_H_
+
+#include
+
+class FakeChecksumValidator : public Cynara::ChecksumValidator {
+public:
+ using Cynara::ChecksumValidator::ChecksumValidator;
+
+ const Checksums &sums(void) {
+ return m_sums;
+ }
+};
+
+#endif /* FAKECHECKSUMVALIDATOR_H_ */
--
2.7.4
From 58d92c8f005be204b6d0cb990d8276aed1f3b76a Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Mon, 12 Jan 2015 15:01:54 +0100
Subject: [PATCH 04/16] Make StorageSerializer a template class
This patch modifies StorageSerializer so that it will be able to use
other streams than std::ostream and its derivatives. Within current
class hierarchy custom output streams with overloaded insertion operator
(operator<<) cannot be used, as it is non-virtual in std::ostream.
Change-Id: I3e713329c55aacfbb8daa23a5c4579d4c5db9f52
---
src/storage/CMakeLists.txt | 3 +-
src/storage/InMemoryStorageBackend.cpp | 6 +--
src/storage/InMemoryStorageBackend.h | 3 +-
src/storage/StorageSerializer.cpp | 92 ----------------------------------
src/storage/StorageSerializer.h | 68 ++++++++++++++++++++++++-
test/CMakeLists.txt | 1 -
test/storage/serializer/dump.cpp | 8 +--
test/storage/serializer/dump_load.cpp | 4 +-
test/storage/serializer/serialize.cpp | 27 +++++-----
9 files changed, 93 insertions(+), 119 deletions(-)
delete mode 100644 src/storage/StorageSerializer.cpp
diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt
index 996b37a..72f0ec2 100644
--- a/src/storage/CMakeLists.txt
+++ b/src/storage/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2014-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.
@@ -29,7 +29,6 @@ SET(LIB_CYNARA_STORAGE_SOURCES
${CYNARA_LIB_CYNARA_STORAGE_PATH}/Integrity.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/Storage.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/StorageDeserializer.cpp
- ${CYNARA_LIB_CYNARA_STORAGE_PATH}/StorageSerializer.cpp
)
INCLUDE_DIRECTORIES(
diff --git a/src/storage/InMemoryStorageBackend.cpp b/src/storage/InMemoryStorageBackend.cpp
index a5e08b1..d6655e2 100644
--- a/src/storage/InMemoryStorageBackend.cpp
+++ b/src/storage/InMemoryStorageBackend.cpp
@@ -100,7 +100,7 @@ void InMemoryStorageBackend::save(void) {
std::string indexFilename = m_dbPath + m_indexFilename;
openDumpFileStream(indexStream, indexFilename + m_backupFilenameSuffix);
- StorageSerializer storageSerializer(indexStream);
+ StorageSerializer storageSerializer(indexStream);
storageSerializer.dump(buckets(), std::bind(&InMemoryStorageBackend::bucketDumpStreamOpener,
this, std::placeholders::_1));
@@ -253,14 +253,14 @@ std::shared_ptr InMemoryStorageBackend::bucketStreamOpener(
}
}
-std::shared_ptr InMemoryStorageBackend::bucketDumpStreamOpener(
+std::shared_ptr > InMemoryStorageBackend::bucketDumpStreamOpener(
const PolicyBucketId &bucketId) {
std::string bucketFilename = m_dbPath + m_bucketFilenamePrefix +
bucketId + m_backupFilenameSuffix;
auto bucketStream = std::make_shared();
openDumpFileStream(bucketStream, bucketFilename);
- return std::make_shared(bucketStream);
+ return std::make_shared >(bucketStream);
}
void InMemoryStorageBackend::postLoadCleanup(bool isBackupValid) {
diff --git a/src/storage/InMemoryStorageBackend.h b/src/storage/InMemoryStorageBackend.h
index c9e63c2..10251c7 100644
--- a/src/storage/InMemoryStorageBackend.h
+++ b/src/storage/InMemoryStorageBackend.h
@@ -71,7 +71,8 @@ protected:
virtual void openDumpFileStream(std::shared_ptr stream,
const std::string &filename);
- std::shared_ptr bucketDumpStreamOpener(const PolicyBucketId &bucketId);
+ std::shared_ptr > bucketDumpStreamOpener(
+ const PolicyBucketId &bucketId);
virtual void postLoadCleanup(bool isBackupValid);
diff --git a/src/storage/StorageSerializer.cpp b/src/storage/StorageSerializer.cpp
deleted file mode 100644
index 9f701dd..0000000
--- a/src/storage/StorageSerializer.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2014-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 src/storage/StorageSerializer.cpp
- * @author Aleksander Zdyb
- * @version 1.0
- * @brief Implementation of Cynara::StorageSerializer methods
- */
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "StorageSerializer.h"
-
-namespace Cynara {
-
-StorageSerializer::StorageSerializer(std::shared_ptr os) : m_outStream(os) {
-}
-
-void StorageSerializer::dump(const Buckets &buckets,
- BucketStreamOpener streamOpener) {
-
- for (const auto bucketIter : buckets) {
- const auto &bucket = bucketIter.second;
-
- dumpFields(bucket.id(), bucket.defaultPolicy().policyType(),
- bucket.defaultPolicy().metadata());
- }
-
- for (const auto bucketIter : buckets) {
- const auto &bucketId = bucketIter.first;
- const auto &bucket = bucketIter.second;
- auto bucketSerializer = streamOpener(bucketId);
-
- if (bucketSerializer != nullptr) {
- bucketSerializer->dump(bucket);
- } else {
- throw BucketSerializationException(bucketId);
- }
- }
-}
-
-void StorageSerializer::dump(const PolicyBucket& bucket) {
- for (auto it = std::begin(bucket); it != std::end(bucket); ++it) {
- const auto &policy = *it;
- dump(policy);
- }
-}
-
-void StorageSerializer::dump(const PolicyKeyFeature &keyFeature) {
- *m_outStream << keyFeature.toString();
-}
-
-void StorageSerializer::dump(const PolicyType &policyType) {
- auto oldFormat = m_outStream->flags();
- *m_outStream << "0x" << std::uppercase << std::hex << policyType;
- m_outStream->flags(oldFormat);
-}
-
-void StorageSerializer::dump(const PolicyResult::PolicyMetadata &metadata) {
- *m_outStream << metadata;
-}
-
-void StorageSerializer::dump(const PolicyCollection::value_type &policy) {
- const auto &key = policy->key();
- const auto &result = policy->result();
-
- dumpFields(key.client(), key.user(), key.privilege(), result.policyType(), result.metadata());
-}
-
-} /* namespace Cynara */
diff --git a/src/storage/StorageSerializer.h b/src/storage/StorageSerializer.h
index 42982b2..40eb784 100644
--- a/src/storage/StorageSerializer.h
+++ b/src/storage/StorageSerializer.h
@@ -25,9 +25,13 @@
#include
#include
+#include
#include
+#include
#include
+#include
+#include
#include
#include
#include
@@ -39,13 +43,14 @@
namespace Cynara {
+template
class StorageSerializer {
public:
typedef std::function(const PolicyBucketId &)>
BucketStreamOpener;
- StorageSerializer(std::shared_ptr os);
+ StorageSerializer(std::shared_ptr os);
virtual ~StorageSerializer() {};
virtual void dump(const Buckets &buckets,
@@ -72,9 +77,68 @@ protected:
void dump(const PolicyCollection::value_type &policy);
private:
- std::shared_ptr m_outStream;
+ std::shared_ptr m_outStream;
};
+template
+StorageSerializer::StorageSerializer(std::shared_ptr os) : m_outStream(os) {
+}
+
+template
+void StorageSerializer::dump(const Buckets &buckets, BucketStreamOpener streamOpener) {
+ for (const auto bucketIter : buckets) {
+ const auto &bucket = bucketIter.second;
+
+ dumpFields(bucket.id(), bucket.defaultPolicy().policyType(),
+ bucket.defaultPolicy().metadata());
+ }
+
+ for (const auto bucketIter : buckets) {
+ const auto &bucketId = bucketIter.first;
+ const auto &bucket = bucketIter.second;
+ auto bucketSerializer = streamOpener(bucketId);
+
+ if (bucketSerializer != nullptr) {
+ bucketSerializer->dump(bucket);
+ } else {
+ throw BucketSerializationException(bucketId);
+ }
+ }
+}
+
+template
+void StorageSerializer::dump(const PolicyBucket &bucket) {
+ for (auto it = std::begin(bucket); it != std::end(bucket); ++it) {
+ const auto &policy = *it;
+ dump(policy);
+ }
+}
+
+template
+void StorageSerializer::dump(const PolicyKeyFeature &keyFeature) {
+ *m_outStream << keyFeature.toString();
+}
+
+template
+void StorageSerializer::dump(const PolicyType &policyType) {
+ auto oldFormat = m_outStream->flags();
+ *m_outStream << "0x" << std::uppercase << std::hex << policyType;
+ m_outStream->flags(oldFormat);
+}
+
+template
+void StorageSerializer::dump(const PolicyResult::PolicyMetadata &metadata) {
+ *m_outStream << metadata;
+}
+
+template
+void StorageSerializer::dump(const PolicyCollection::value_type &policy) {
+ const auto &key = policy->key();
+ const auto &result = policy->result();
+
+ dumpFields(key.client(), key.user(), key.privilege(), result.policyType(), result.metadata());
+}
+
} /* namespace Cynara */
#endif /* SRC_STORAGE_STORAGESERIALIZER_H_ */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 5050634..9cf89d7 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -68,7 +68,6 @@ SET(CYNARA_SOURCES_FOR_TESTS
${CYNARA_SRC}/storage/Integrity.cpp
${CYNARA_SRC}/storage/Storage.cpp
${CYNARA_SRC}/storage/StorageDeserializer.cpp
- ${CYNARA_SRC}/storage/StorageSerializer.cpp
)
SET(CYNARA_TESTS_SOURCES
diff --git a/test/storage/serializer/dump.cpp b/test/storage/serializer/dump.cpp
index 2eafcf7..1daaf32 100644
--- a/test/storage/serializer/dump.cpp
+++ b/test/storage/serializer/dump.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -51,7 +51,7 @@ TEST(serializer_dump, dump_empty_bucket) {
auto oss = std::make_shared();
PolicyBucket bucket("empty");
- StorageSerializer serializer(oss);
+ StorageSerializer serializer(oss);
serializer.dump(bucket);
ASSERT_EQ("", oss->str());
@@ -69,7 +69,7 @@ TEST(serializer_dump, dump_bucket) {
Policy::simpleWithKey(pk2, DENY) }));
auto outStream = std::make_shared();
- StorageSerializer serializer(outStream);
+ StorageSerializer serializer(outStream);
serializer.dump(bucket);
// Split stream into records
@@ -99,7 +99,7 @@ TEST(serializer_dump, dump_bucket_bucket) {
Policy::bucketWithKey(pk3, bucketId) }};
auto outStream = std::make_shared();
- StorageSerializer serializer(outStream);
+ StorageSerializer serializer(outStream);
serializer.dump(bucket);
// Split stream into records
diff --git a/test/storage/serializer/dump_load.cpp b/test/storage/serializer/dump_load.cpp
index f3eff9b..cd4ce5c 100644
--- a/test/storage/serializer/dump_load.cpp
+++ b/test/storage/serializer/dump_load.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -54,7 +54,7 @@ TEST(dump_load, bucket) {
auto ioStream = std::make_shared();
- StorageSerializer serializer(ioStream);
+ StorageSerializer serializer(ioStream);
serializer.dump(bucket);
BucketDeserializer deserializer(ioStream);
diff --git a/test/storage/serializer/serialize.cpp b/test/storage/serializer/serialize.cpp
index 938283d..1681a5b 100644
--- a/test/storage/serializer/serialize.cpp
+++ b/test/storage/serializer/serialize.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -37,21 +37,24 @@
class FakeStreamForBucketId {
public:
+ typedef std::shared_ptr >
+ StringstreamStorageSerializerPtr;
+
MOCK_METHOD1(streamForBucketId,
- std::shared_ptr(const Cynara::PolicyBucketId &));
+ StringstreamStorageSerializerPtr(const Cynara::PolicyBucketId &));
- Cynara::StorageSerializer::BucketStreamOpener streamOpener() {
+ Cynara::StorageSerializer::BucketStreamOpener streamOpener() {
return std::bind(&FakeStreamForBucketId::streamForBucketId, this, std::placeholders::_1);
}
};
// Fake StorageSerializer for Cynara::PolicyBucket
-class FakeStorageSerializer : public Cynara::StorageSerializer {
+class FakeStorageSerializer : public Cynara::StorageSerializer {
public:
- FakeStorageSerializer(std::shared_ptr o) : Cynara::StorageSerializer(o),
- outStream(o) {}
+ FakeStorageSerializer(std::shared_ptr o)
+ : Cynara::StorageSerializer(o), outStream(o) {}
MOCK_METHOD1(dump, void(const Cynara::PolicyBucket &bucket));
- std::shared_ptr outStream;
+ std::shared_ptr outStream;
};
class StorageSerializerFixture : public ::testing::Test {
@@ -67,8 +70,8 @@ using namespace Cynara;
// Be sure no calls to streamForBucketId() are made
// and output stream is not touched
TEST_F(StorageSerializerFixture, dump_buckets_empty) {
- auto outStream = std::make_shared();
- StorageSerializer serializer(outStream);
+ auto outStream = std::make_shared();
+ StorageSerializer serializer(outStream);
serializer.dump(Buckets(), fakeStreamOpener.streamOpener());
// Stream should be empty
@@ -83,7 +86,7 @@ TEST_F(StorageSerializerFixture, dump_buckets) {
// Will be returned as serializer for buckets
auto fakeBucketSerializer = std::make_shared(
- std::make_shared());
+ std::make_shared());
buckets = {
{ "bucket1", PolicyBucket("bucket1", PredefinedPolicyType::DENY) },
@@ -93,7 +96,7 @@ TEST_F(StorageSerializerFixture, dump_buckets) {
};
auto outStream = std::make_shared();
- StorageSerializer dbSerializer(outStream);
+ StorageSerializer dbSerializer(outStream);
// Make sure stream was opened for each bucket
EXPECT_CALL(fakeStreamOpener, streamForBucketId(_))
@@ -128,7 +131,7 @@ TEST_F(StorageSerializerFixture, dump_buckets_io_error) {
};
auto outStream = std::make_shared();
- StorageSerializer dbSerializer(outStream);
+ StorageSerializer dbSerializer(outStream);
// Make sure stream was opened for each bucket
EXPECT_CALL(fakeStreamOpener, streamForBucketId(_))
--
2.7.4
From bf8b0794dbe4d401430cae787e6bc3e6e0d09224 Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Thu, 15 Jan 2015 08:19:15 +0100
Subject: [PATCH 05/16] Introduce ChecksumStream
ChecksumStream will replace std::ofstream for saving database contents
in storage. This way data will be not only written to the files, but
also its checksums will be computed and stored in given stream (database
index equivalent for storing checksums).
Checksum computing is performed during stream destruction in order to be
sure that all necessary data was already collected.
Change-Id: I4a9ff2e29361f337cacd790d77364feca854a706
---
src/storage/CMakeLists.txt | 1 +
src/storage/ChecksumStream.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++
src/storage/ChecksumStream.h | 70 +++++++++++++++++++++++++++++++++++++++++
test/CMakeLists.txt | 1 +
4 files changed, 143 insertions(+)
create mode 100644 src/storage/ChecksumStream.cpp
create mode 100644 src/storage/ChecksumStream.h
diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt
index 72f0ec2..f75bc06 100644
--- a/src/storage/CMakeLists.txt
+++ b/src/storage/CMakeLists.txt
@@ -24,6 +24,7 @@ SET(CYNARA_LIB_CYNARA_STORAGE_PATH ${CYNARA_PATH}/storage)
SET(LIB_CYNARA_STORAGE_SOURCES
${CYNARA_LIB_CYNARA_STORAGE_PATH}/BucketDeserializer.cpp
+ ${CYNARA_LIB_CYNARA_STORAGE_PATH}/ChecksumStream.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/ChecksumValidator.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/InMemoryStorageBackend.cpp
${CYNARA_LIB_CYNARA_STORAGE_PATH}/Integrity.cpp
diff --git a/src/storage/ChecksumStream.cpp b/src/storage/ChecksumStream.cpp
new file mode 100644
index 0000000..551307e
--- /dev/null
+++ b/src/storage/ChecksumStream.cpp
@@ -0,0 +1,71 @@
+/*
+ * 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 src/storage/ChecksumStream.cpp
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief This file contains ChecksumStream implementation.
+ */
+
+#include
+#include
+
+#include
+
+#include
+
+#include "ChecksumStream.h"
+
+namespace Cynara {
+
+const char ChecksumStream::m_fieldSeparator(PathConfig::StoragePath::fieldSeparator);
+const char ChecksumStream::m_recordSeparator(PathConfig::StoragePath::recordSeparator);
+
+ChecksumStream::~ChecksumStream() {
+ if (!std::uncaught_exception()) {
+ save();
+ }
+}
+
+ChecksumStream& ChecksumStream::operator<<(std::ostream& (*manip)(std::ostream&)) {
+ m_bufStream << manip;
+ m_outStream << manip;
+ return *this;
+}
+
+void ChecksumStream::open(const std::string &filename, std::ios_base::openmode mode) {
+ m_outStream.open(filename, mode);
+}
+
+bool ChecksumStream::is_open(void) const {
+ return m_outStream.is_open();
+}
+
+std::ios_base::fmtflags ChecksumStream::flags(void) const {
+ return m_outStream.flags();
+}
+
+std::ios_base::fmtflags ChecksumStream::flags(std::ios_base::fmtflags flags) {
+ return m_outStream.flags(flags);
+}
+
+void ChecksumStream::save() {
+ m_outStream.close();
+ *m_chsStream << m_filename << m_fieldSeparator << ChecksumValidator::generate(m_bufStream.str())
+ << m_recordSeparator;
+}
+
+} // namespace Cynara
diff --git a/src/storage/ChecksumStream.h b/src/storage/ChecksumStream.h
new file mode 100644
index 0000000..ddc6e6f
--- /dev/null
+++ b/src/storage/ChecksumStream.h
@@ -0,0 +1,70 @@
+/*
+ * 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 src/storage/ChecksumStream.h
+ * @author Pawel Wieczorek
+ * @version 1.0
+ * @brief This file contains ChecksumStream header.
+ */
+
+#ifndef SRC_STORAGE_CHECKSUMSTREAM_H_
+#define SRC_STORAGE_CHECKSUMSTREAM_H_
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Cynara {
+
+class ChecksumStream {
+public:
+ ChecksumStream(const std::string &filename, const std::shared_ptr &stream)
+ : m_chsStream(stream), m_filename(filename) {
+ }
+ ~ChecksumStream();
+
+ template
+ ChecksumStream& operator<<(const Type &item);
+ ChecksumStream& operator<<(std::ostream& (*manip)(std::ostream&));
+
+ void open(const std::string &filename, std::ios_base::openmode mode);
+ bool is_open(void) const;
+ std::ios_base::fmtflags flags(void) const;
+ std::ios_base::fmtflags flags(std::ios_base::fmtflags flags);
+
+private:
+ void save(void);
+
+ std::shared_ptr m_chsStream;
+ std::ofstream m_outStream;
+ std::stringstream m_bufStream;
+ const std::string m_filename;
+ static const char m_fieldSeparator;
+ static const char m_recordSeparator;
+};
+
+template
+ChecksumStream& ChecksumStream::operator<<(const Type& item) {
+ m_bufStream << item;
+ m_outStream << item;
+ return *this;
+}
+
+} // namespace Cynara
+
+#endif // SRC_STORAGE_CHECKSUMSTREAM_H_
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9cf89d7..189268d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -63,6 +63,7 @@ SET(CYNARA_SOURCES_FOR_TESTS
${CYNARA_SRC}/helpers/creds-commons/creds-commons.cpp
${CYNARA_SRC}/service/main/CmdlineParser.cpp
${CYNARA_SRC}/storage/BucketDeserializer.cpp
+ ${CYNARA_SRC}/storage/ChecksumStream.cpp
${CYNARA_SRC}/storage/ChecksumValidator.cpp
${CYNARA_SRC}/storage/InMemoryStorageBackend.cpp
${CYNARA_SRC}/storage/Integrity.cpp
--
2.7.4
From f08a80ee755ba5aed0450bb04eaa235e3966ab05 Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Tue, 23 Dec 2014 17:18:16 +0100
Subject: [PATCH 06/16] Adjust InMemoryStorageBackend to ChecksumValidator
InMemoryStorageBackend uses ChecksumValidator as a checksum loader and
comparator. This patch also includes files needed by storage unit tests
to work properly.
Change-Id: I541975351275bd6a30e7cf627697c9657161312f
---
src/storage/InMemoryStorageBackend.cpp | 27 ++++++++++++++++++++-------
src/storage/InMemoryStorageBackend.h | 9 +++++++--
src/storage/Integrity.cpp | 8 +++++++-
test/db/db2/checksum | 1 +
test/db/db3/checksum | 2 ++
test/db/db4/checksum | 3 +++
test/db/db5/checksum | 3 +++
test/db/db6/checksum | 3 +++
test/db/db6/checksum~ | 3 +++
9 files changed, 49 insertions(+), 10 deletions(-)
create mode 100644 test/db/db2/checksum
create mode 100644 test/db/db3/checksum
create mode 100644 test/db/db4/checksum
create mode 100644 test/db/db5/checksum
create mode 100644 test/db/db6/checksum
create mode 100644 test/db/db6/checksum~
diff --git a/src/storage/InMemoryStorageBackend.cpp b/src/storage/InMemoryStorageBackend.cpp
index d6655e2..249eccf 100644
--- a/src/storage/InMemoryStorageBackend.cpp
+++ b/src/storage/InMemoryStorageBackend.cpp
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -51,6 +52,7 @@
namespace Cynara {
+const std::string InMemoryStorageBackend::m_chsFilename(PathConfig::StoragePath::checksumFilename);
const std::string InMemoryStorageBackend::m_indexFilename(PathConfig::StoragePath::indexFilename);
const std::string InMemoryStorageBackend::m_backupFilenameSuffix(
PathConfig::StoragePath::backupFilenameSuffix);
@@ -58,26 +60,32 @@ const std::string InMemoryStorageBackend::m_bucketFilenamePrefix(
PathConfig::StoragePath::bucketFilenamePrefix);
InMemoryStorageBackend::InMemoryStorageBackend(const std::string &path) : m_dbPath(path),
- m_integrity(path) {
+ m_checksum(path), m_integrity(path) {
}
void InMemoryStorageBackend::load(void) {
bool isBackupValid = m_integrity.backupGuardExists();
std::string bucketSuffix = "";
std::string indexFilename = m_dbPath + m_indexFilename;
+ std::string chsFilename = m_dbPath + m_chsFilename;
if (isBackupValid) {
bucketSuffix += m_backupFilenameSuffix;
indexFilename += m_backupFilenameSuffix;
+ chsFilename += m_backupFilenameSuffix;
}
try {
+ auto chsStream = std::make_shared();
+ openFileStream(chsStream, chsFilename, isBackupValid);
+ m_checksum.load(*chsStream);
+
auto indexStream = std::make_shared();
- openFileStream(indexStream, indexFilename);
+ openFileStream(indexStream, indexFilename, isBackupValid);
StorageDeserializer storageDeserializer(indexStream,
std::bind(&InMemoryStorageBackend::bucketStreamOpener, this,
- std::placeholders::_1, bucketSuffix));
+ std::placeholders::_1, bucketSuffix, isBackupValid));
storageDeserializer.initBuckets(buckets());
storageDeserializer.loadBuckets(buckets());
@@ -86,6 +94,7 @@ void InMemoryStorageBackend::load(void) {
buckets().clear();
// TODO: Implement emergency mode toggle
}
+ m_checksum.clear();
if (!hasBucket(defaultPolicyBucketId)) {
LOGN("Creating defaultBucket.");
@@ -222,7 +231,7 @@ void InMemoryStorageBackend::erasePolicies(const PolicyBucketId &bucketId, bool
}
void InMemoryStorageBackend::openFileStream(std::shared_ptr stream,
- const std::string &filename) {
+ const std::string &filename, bool isBackupValid) {
// TODO: Consider adding exceptions to streams and handling them:
// stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
stream->open(filename);
@@ -230,6 +239,8 @@ void InMemoryStorageBackend::openFileStream(std::shared_ptr strea
if (!stream->is_open()) {
throw FileNotFoundException(filename);
}
+
+ m_checksum.compare(*stream, filename, isBackupValid);
}
void InMemoryStorageBackend::openDumpFileStream(std::shared_ptr stream,
@@ -242,14 +253,16 @@ void InMemoryStorageBackend::openDumpFileStream(std::shared_ptr s
}
std::shared_ptr InMemoryStorageBackend::bucketStreamOpener(
- const PolicyBucketId &bucketId, const std::string &filenameSuffix) {
+ const PolicyBucketId &bucketId, const std::string &filenameSuffix, bool isBackupValid) {
std::string bucketFilename = m_dbPath + m_bucketFilenamePrefix + bucketId + filenameSuffix;
auto bucketStream = std::make_shared();
try {
- openFileStream(bucketStream, bucketFilename);
+ openFileStream(bucketStream, bucketFilename, isBackupValid);
return std::make_shared(bucketStream);
} catch (const FileNotFoundException &) {
return nullptr;
+ } catch (const std::bad_alloc &) {
+ return nullptr;
}
}
@@ -269,7 +282,7 @@ void InMemoryStorageBackend::postLoadCleanup(bool isBackupValid) {
}
//in case there were unnecessary files in db directory
m_integrity.deleteNonIndexedFiles(std::bind(&InMemoryStorageBackend::hasBucket, this,
- std::placeholders::_1));
+ std::placeholders::_1));
}
} /* namespace Cynara */
diff --git a/src/storage/InMemoryStorageBackend.h b/src/storage/InMemoryStorageBackend.h
index 10251c7..65af96b 100644
--- a/src/storage/InMemoryStorageBackend.h
+++ b/src/storage/InMemoryStorageBackend.h
@@ -35,6 +35,7 @@
#include
#include
+#include
#include
#include
#include
@@ -65,9 +66,11 @@ public:
const PolicyKey &filter);
protected:
- void openFileStream(std::shared_ptr stream, const std::string &filename);
+ void openFileStream(std::shared_ptr stream, const std::string &filename,
+ bool isBackupValid);
std::shared_ptr bucketStreamOpener(const PolicyBucketId &bucketId,
- const std::string &fileNameSuffix);
+ const std::string &fileNameSuffix,
+ bool isBackupValid);
virtual void openDumpFileStream(std::shared_ptr stream,
const std::string &filename);
@@ -79,7 +82,9 @@ protected:
private:
std::string m_dbPath;
Buckets m_buckets;
+ ChecksumValidator m_checksum;
Integrity m_integrity;
+ static const std::string m_chsFilename;
static const std::string m_indexFilename;
static const std::string m_backupFilenameSuffix;
static const std::string m_bucketFilenamePrefix;
diff --git a/src/storage/Integrity.cpp b/src/storage/Integrity.cpp
index 5dfa624..0b8e583 100644
--- a/src/storage/Integrity.cpp
+++ b/src/storage/Integrity.cpp
@@ -83,6 +83,7 @@ void Integrity::syncDatabase(const Buckets &buckets, bool syncBackup) {
}
syncElement(m_dbPath + m_indexFilename + suffix);
+ syncElement(m_dbPath + PathConfig::StoragePath::checksumFilename + suffix);
syncDirectory(m_dbPath);
}
@@ -152,7 +153,8 @@ void Integrity::syncElement(const std::string &filename, int flags, mode_t mode)
if (fileFd < 0) {
int err = errno;
if (err != EEXIST) {
- LOGE("'open' function error [%d] : <%s>", err, strerror(err));
+ LOGE("File <%s> : 'open' function error [%d] : <%s>", filename.c_str(), err,
+ strerror(err));
throw UnexpectedErrorException(err, strerror(err));
} else {
throw CannotCreateFileException(filename);
@@ -194,9 +196,12 @@ void Integrity::createPrimaryHardLinks(const Buckets &buckets) {
}
const auto &indexFilename = m_dbPath + m_indexFilename;
+ const auto &checksumFilename = m_dbPath + PathConfig::StoragePath::checksumFilename;
deleteHardLink(indexFilename);
createHardLink(indexFilename + m_backupFilenameSuffix, indexFilename);
+ deleteHardLink(checksumFilename);
+ createHardLink(checksumFilename + m_backupFilenameSuffix, checksumFilename);
}
void Integrity::deleteBackupHardLinks(const Buckets &buckets) {
@@ -209,6 +214,7 @@ void Integrity::deleteBackupHardLinks(const Buckets &buckets) {
}
deleteHardLink(m_dbPath + m_indexFilename + m_backupFilenameSuffix);
+ deleteHardLink(m_dbPath + PathConfig::StoragePath::checksumFilename + m_backupFilenameSuffix);
}
void Integrity::createHardLink(const std::string &oldName, const std::string &newName) {
diff --git a/test/db/db2/checksum b/test/db/db2/checksum
new file mode 100644
index 0000000..a91e13a
--- /dev/null
+++ b/test/db/db2/checksum
@@ -0,0 +1 @@
+buckets;$1$$QYBGLyef4xp18EzYIMd/U0
diff --git a/test/db/db3/checksum b/test/db/db3/checksum
new file mode 100644
index 0000000..39a8d89
--- /dev/null
+++ b/test/db/db3/checksum
@@ -0,0 +1,2 @@
+buckets;$1$$QYBGLyef4xp18EzYIMd/U0
+_;$1$$qRPK7m23GJusamGpoGLby/
diff --git a/test/db/db4/checksum b/test/db/db4/checksum
new file mode 100644
index 0000000..e2477f0
--- /dev/null
+++ b/test/db/db4/checksum
@@ -0,0 +1,3 @@
+buckets;$1$$Z6OUrCl62KbAaZ16Cexgm0
+_;$1$$qRPK7m23GJusamGpoGLby/
+_additional;$1$$qRPK7m23GJusamGpoGLby/
diff --git a/test/db/db5/checksum b/test/db/db5/checksum
new file mode 100644
index 0000000..b578233
--- /dev/null
+++ b/test/db/db5/checksum
@@ -0,0 +1,3 @@
+buckets;$1$$Z6OUrCl62KbAaZ16Cexgm0
+_;$1$$qRPK7m23GJusamGpoGLby/
+_additional;$1$$NIRf1PrhNP0QOAOGJ4VDf/
diff --git a/test/db/db6/checksum b/test/db/db6/checksum
new file mode 100644
index 0000000..a951841
--- /dev/null
+++ b/test/db/db6/checksum
@@ -0,0 +1,3 @@
+buckets;$1$$Z6OUrCl62KbAaZ16Cexgm0
+_;$1$$qRPK7m23GJusamGpoGLby/
+_additional;$1$$Shj03wOSJf.nmFjldRTO.1
diff --git a/test/db/db6/checksum~ b/test/db/db6/checksum~
new file mode 100644
index 0000000..e2477f0
--- /dev/null
+++ b/test/db/db6/checksum~
@@ -0,0 +1,3 @@
+buckets;$1$$Z6OUrCl62KbAaZ16Cexgm0
+_;$1$$qRPK7m23GJusamGpoGLby/
+_additional;$1$$qRPK7m23GJusamGpoGLby/
--
2.7.4
From e47f0b094278df45f6d38483718fafeba4d558d0 Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Thu, 15 Jan 2015 10:53:18 +0100
Subject: [PATCH 07/16] Adjust InMemoryStorageBackend to ChecksumStream
Now InMemoryStorageBackend uses ChecksumStream instead of std::ofstream.
New member function dumpDatabase() was introduced in order to destruct
database index stream before calling integrity mechanism.
Change-Id: I5ea943e1ec21f02cea97699993ddbd0f3eeb0a62
---
src/storage/InMemoryStorageBackend.cpp | 43 +++++++++++++++++-----------------
src/storage/InMemoryStorageBackend.h | 24 +++++++++++++++----
2 files changed, 40 insertions(+), 27 deletions(-)
diff --git a/src/storage/InMemoryStorageBackend.cpp b/src/storage/InMemoryStorageBackend.cpp
index 249eccf..57a4b56 100644
--- a/src/storage/InMemoryStorageBackend.cpp
+++ b/src/storage/InMemoryStorageBackend.cpp
@@ -35,7 +35,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -105,13 +104,11 @@ void InMemoryStorageBackend::load(void) {
}
void InMemoryStorageBackend::save(void) {
- auto indexStream = std::make_shared();
- std::string indexFilename = m_dbPath + m_indexFilename;
- openDumpFileStream(indexStream, indexFilename + m_backupFilenameSuffix);
+ std::string checksumFilename = m_dbPath + m_chsFilename;
+ auto chsStream = std::make_shared();
+ openDumpFileStream(chsStream, checksumFilename + m_backupFilenameSuffix);
- StorageSerializer storageSerializer(indexStream);
- storageSerializer.dump(buckets(), std::bind(&InMemoryStorageBackend::bucketDumpStreamOpener,
- this, std::placeholders::_1));
+ dumpDatabase(chsStream);
m_integrity.syncDatabase(buckets(), true);
m_integrity.createBackupGuard();
@@ -230,7 +227,17 @@ void InMemoryStorageBackend::erasePolicies(const PolicyBucketId &bucketId, bool
}
}
-void InMemoryStorageBackend::openFileStream(std::shared_ptr stream,
+void InMemoryStorageBackend::dumpDatabase(const std::shared_ptr &chsStream) {
+ auto indexStream = std::make_shared(m_indexFilename, chsStream);
+ std::string indexFilename = m_dbPath + m_indexFilename;
+ openDumpFileStream(indexStream, indexFilename + m_backupFilenameSuffix);
+
+ StorageSerializer storageSerializer(indexStream);
+ storageSerializer.dump(buckets(), std::bind(&InMemoryStorageBackend::bucketDumpStreamOpener,
+ this, std::placeholders::_1, chsStream));
+}
+
+void InMemoryStorageBackend::openFileStream(const std::shared_ptr &stream,
const std::string &filename, bool isBackupValid) {
// TODO: Consider adding exceptions to streams and handling them:
// stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
@@ -243,15 +250,6 @@ void InMemoryStorageBackend::openFileStream(std::shared_ptr strea
m_checksum.compare(*stream, filename, isBackupValid);
}
-void InMemoryStorageBackend::openDumpFileStream(std::shared_ptr stream,
- const std::string &filename) {
- stream->open(filename, std::ofstream::out | std::ofstream::trunc);
-
- if (!stream->is_open()) {
- throw CannotCreateFileException(filename);
- }
-}
-
std::shared_ptr InMemoryStorageBackend::bucketStreamOpener(
const PolicyBucketId &bucketId, const std::string &filenameSuffix, bool isBackupValid) {
std::string bucketFilename = m_dbPath + m_bucketFilenamePrefix + bucketId + filenameSuffix;
@@ -266,14 +264,15 @@ std::shared_ptr InMemoryStorageBackend::bucketStreamOpener(
}
}
-std::shared_ptr > InMemoryStorageBackend::bucketDumpStreamOpener(
- const PolicyBucketId &bucketId) {
+std::shared_ptr > InMemoryStorageBackend::bucketDumpStreamOpener(
+ const PolicyBucketId &bucketId, const std::shared_ptr &chsStream) {
std::string bucketFilename = m_dbPath + m_bucketFilenamePrefix +
bucketId + m_backupFilenameSuffix;
- auto bucketStream = std::make_shared();
+ auto bucketStream = std::make_shared(m_bucketFilenamePrefix + bucketId,
+ chsStream);
- openDumpFileStream(bucketStream, bucketFilename);
- return std::make_shared >(bucketStream);
+ openDumpFileStream(bucketStream, bucketFilename);
+ return std::make_shared >(bucketStream);
}
void InMemoryStorageBackend::postLoadCleanup(bool isBackupValid) {
diff --git a/src/storage/InMemoryStorageBackend.h b/src/storage/InMemoryStorageBackend.h
index 65af96b..ea1f2bd 100644
--- a/src/storage/InMemoryStorageBackend.h
+++ b/src/storage/InMemoryStorageBackend.h
@@ -27,6 +27,7 @@
#include
#include
+#include
#include
#include
#include
@@ -35,6 +36,7 @@
#include
#include
+#include
#include
#include
#include
@@ -66,16 +68,18 @@ public:
const PolicyKey &filter);
protected:
- void openFileStream(std::shared_ptr stream, const std::string &filename,
+ void dumpDatabase(const std::shared_ptr &chsStream);
+ void openFileStream(const std::shared_ptr &stream, const std::string &filename,
bool isBackupValid);
std::shared_ptr bucketStreamOpener(const PolicyBucketId &bucketId,
const std::string &fileNameSuffix,
bool isBackupValid);
- virtual void openDumpFileStream(std::shared_ptr stream,
- const std::string &filename);
- std::shared_ptr > bucketDumpStreamOpener(
- const PolicyBucketId &bucketId);
+ template
+ void openDumpFileStream(const std::shared_ptr &stream,
+ const std::string &filename);
+ std::shared_ptr > bucketDumpStreamOpener(
+ const PolicyBucketId &bucketId, const std::shared_ptr &chsStream);
virtual void postLoadCleanup(bool isBackupValid);
@@ -98,6 +102,16 @@ protected:
}
};
+template
+void InMemoryStorageBackend::openDumpFileStream(const std::shared_ptr &stream,
+ const std::string &filename) {
+ stream->open(filename, std::ofstream::out | std::ofstream::trunc);
+
+ if (!stream->is_open()) {
+ throw CannotCreateFileException(filename);
+ }
+}
+
} /* namespace Cynara */
#endif /* SRC_STORAGE_INMEMORYSTORAGEBACKEND_H_ */
--
2.7.4
From d760937d27e7c88fd61796465544810b0bdfb799 Mon Sep 17 00:00:00 2001
From: Pawel Wieczorek
Date: Wed, 4 Feb 2015 15:05:30 +0100
Subject: [PATCH 08/16] Prepare service for database corruption handling
When database corruption is detected, no administrative actions are
allowed and all responses to check requests are DENY. Administrative API
has to be informed about detected corruption. This patch modifies
protocol so that this information is passed.
Unit tests are also adjusted to the protocol changes this patch
introduces.
Change-Id: If3ab5d6ca1671167890956b986a4768cc828f3f5
---
src/common/protocol/ProtocolAdmin.cpp | 57 ++++++---
src/common/response/AdminCheckResponse.h | 13 +-
src/common/response/CodeResponse.h | 4 +-
src/common/response/DescriptionListResponse.h | 12 +-
src/common/response/ListResponse.h | 13 +-
src/service/logic/Logic.cpp | 134 +++++++++++++--------
src/service/logic/Logic.h | 2 +
test/common/protocols/admin/admincheckresponse.cpp | 72 ++++++++---
.../protocols/admin/descriptionlistresponse.cpp | 69 ++++++++---
test/common/protocols/admin/listresponse.cpp | 76 ++++++++----
10 files changed, 320 insertions(+), 132 deletions(-)
diff --git a/src/common/protocol/ProtocolAdmin.cpp b/src/common/protocol/ProtocolAdmin.cpp
index 238374b..35eedd8 100644
--- a/src/common/protocol/ProtocolAdmin.cpp
+++ b/src/common/protocol/ProtocolAdmin.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -17,6 +17,7 @@
* @file src/common/protocol/ProtocolAdmin.cpp
* @author Lukasz Wojciechowski
* @author Adam Malinowski
+ * @author Pawel Wieczorek
* @version 1.0
* @brief This file implements protocol class for administration
*/
@@ -233,17 +234,20 @@ ResponsePtr ProtocolAdmin::deserializeAdminCheckResponse(void) {
PolicyType result;
PolicyResult::PolicyMetadata additionalInfo;
bool bucketValid;
+ bool dbCorrupted;
ProtocolDeserialization::deserialize(m_frameHeader, result);
ProtocolDeserialization::deserialize(m_frameHeader, additionalInfo);
ProtocolDeserialization::deserialize(m_frameHeader, bucketValid);
+ ProtocolDeserialization::deserialize(m_frameHeader, dbCorrupted);
const PolicyResult policyResult(result, additionalInfo);
- LOGD("Deserialized AdminCheckResponse: result [%" PRIu16 "], metadata <%s>, bucketValid [%d]",
- policyResult.policyType(), policyResult.metadata().c_str(), static_cast(bucketValid));
+ LOGD("Deserialized AdminCheckResponse: result [%" PRIu16 "], metadata <%s>, bucketValid [%d], "
+ "dbCorrupted [%d]", policyResult.policyType(), policyResult.metadata().c_str(),
+ static_cast(bucketValid), static_cast(dbCorrupted));
- return std::make_shared(policyResult, bucketValid,
+ return std::make_shared(policyResult, bucketValid, dbCorrupted,
m_frameHeader.sequenceNumber());
}
@@ -269,10 +273,14 @@ ResponsePtr ProtocolAdmin::deserializeDescriptionListResponse(void) {
ProtocolDeserialization::deserialize(m_frameHeader, descriptions[fields].name);
}
- LOGD("Deserialized DescriptionListResponse: number of descriptions [%" PRIu16 "]",
- descriptionsCount);
+ bool dbCorrupted;
+ ProtocolDeserialization::deserialize(m_frameHeader, dbCorrupted);
- return std::make_shared(descriptions, m_frameHeader.sequenceNumber());
+ LOGD("Deserialized DescriptionListResponse: number of descriptions [%" PRIu16 "], "
+ "dbCorrupted [%d]", descriptionsCount, static_cast(dbCorrupted));
+
+ return std::make_shared(descriptions, dbCorrupted,
+ m_frameHeader.sequenceNumber());
}
ResponsePtr ProtocolAdmin::deserializeListResponse(void) {
@@ -298,13 +306,18 @@ ResponsePtr ProtocolAdmin::deserializeListResponse(void) {
PolicyResult(policyType, metadata)));
}
- bool isBucketValid;
- ProtocolDeserialization::deserialize(m_frameHeader, isBucketValid);
+ bool bucketValid;
+ bool dbCorrupted;
+ ProtocolDeserialization::deserialize(m_frameHeader, bucketValid);
+ ProtocolDeserialization::deserialize(m_frameHeader, dbCorrupted);
+
+ LOGD("Deserialized ListResponse: number of policies [%" PRIu16 "], bucketValid [%d], "
+ "dbCorrupted [%d]", policiesCount, static_cast(bucketValid),
+ static_cast(dbCorrupted));
- LOGD("Deserialized ListResponse: number of policies [%" PRIu16 "], isBucketValid [%d]",
- policiesCount, isBucketValid);
+ return std::make_shared(policies, bucketValid, dbCorrupted,
+ m_frameHeader.sequenceNumber());
- return std::make_shared(policies, isBucketValid, m_frameHeader.sequenceNumber());
}
ResponsePtr ProtocolAdmin::extractResponseFromBuffer(BinaryQueuePtr bufferQueue) {
@@ -471,9 +484,10 @@ void ProtocolAdmin::execute(RequestContextPtr context, SetPoliciesRequestPtr req
void ProtocolAdmin::execute(RequestContextPtr context, AdminCheckResponsePtr response) {
LOGD("Serializing AdminCheckResponse: op [%" PRIu8 "], sequenceNumber [%" PRIu16 "], "
- "policyType [%" PRIu16 "], metadata <%s>, bucketValid [%d]", OpAdminCheckPolicyResponse,
- response->sequenceNumber(), response->result().policyType(),
- response->result().metadata().c_str(), static_cast(response->isBucketValid()));
+ "policyType [%" PRIu16 "], metadata <%s>, bucketValid [%d], dbCorrupted [%d]",
+ OpAdminCheckPolicyResponse, response->sequenceNumber(), response->result().policyType(),
+ response->result().metadata().c_str(), static_cast(response->isBucketValid()),
+ static_cast