1 #include <cppunit/CompilerOutputter.h>
2 #include <cppunit/TestCaller.h>
3 #include <cppunit/TestFixture.h>
4 #include <cppunit/extensions/TestFactoryRegistry.h>
5 #include <cppunit/ui/text/TestRunner.h>
6
7 #include <fcntl.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
12 #include "fileerror.hh"
13 #include "fileutils.hh"
14 #include "testpaths.h"
15 #include "yapetfile.hh"
16
17 constexpr auto TEST_FILE{BUILDDIR "/yapet-yapetfile-test"};
18
19 class YapetFileMock : public yapet::YapetFile {
20 public:
YapetFileMock(bool create,bool secure)21 YapetFileMock(bool create, bool secure)
22 : YapetFile{TEST_FILE, create, secure} {}
23
YapetFileMock(YapetFileMock && other)24 YapetFileMock(YapetFileMock&& other) : YapetFile{std::move(other)} {}
25
operator =(YapetFileMock && other)26 YapetFile& operator=(YapetFileMock&& other) {
27 return yapet::YapetFile::operator=(std::move(other));
28 }
29
hasValidFormat()30 bool hasValidFormat() { throw std::runtime_error("Not implemented"); }
31
readIdentifier()32 yapet::SecureArray readIdentifier() {
33 throw std::runtime_error("Not implemented");
34 }
35
readUnencryptedMetaData()36 yapet::SecureArray readUnencryptedMetaData() {
37 throw std::runtime_error("Not implemented");
38 }
39
readHeader()40 yapet::SecureArray readHeader() {
41 throw std::runtime_error("Not implemented");
42 }
43
readPasswordRecords()44 std::list<yapet::SecureArray> readPasswordRecords() {
45 throw std::runtime_error("Not implemented");
46 }
47
writeIdentifier()48 void writeIdentifier() { throw std::runtime_error("Not implemented"); }
49
writeUnencryptedMetaData(const yapet::SecureArray &)50 void writeUnencryptedMetaData(const yapet::SecureArray&) {
51 throw std::runtime_error("Not implemented");
52 }
53
writeHeader(const yapet::SecureArray &)54 void writeHeader(const yapet::SecureArray&) {
55 throw std::runtime_error("Not implemented");
56 }
57
writePasswordRecords(const std::list<yapet::SecureArray> &)58 void writePasswordRecords(const std::list<yapet::SecureArray>&) {
59 throw std::runtime_error("Not implemented");
60 }
61
recognitionString() const62 const std::uint8_t* recognitionString() const {
63 throw std::runtime_error("Not implemented");
64 }
65
recognitionStringSize() const66 int recognitionStringSize() const {
67 throw std::runtime_error("Not implemented");
68 }
69
open()70 void open() { openRawFile(); }
71 };
72
73 class YapetFileTest : public CppUnit::TestFixture {
74 public:
suite()75 static CppUnit::TestSuite* suite() {
76 CppUnit::TestSuite* suiteOfTests =
77 new CppUnit::TestSuite("YapetFile test");
78 suiteOfTests->addTest(new CppUnit::TestCaller<YapetFileTest>{
79 "should fail on non existing file",
80 &YapetFileTest::throwOnNonExisting});
81 suiteOfTests->addTest(new CppUnit::TestCaller<YapetFileTest>{
82 "should create new file with secure permissions",
83 &YapetFileTest::createNewFile});
84 suiteOfTests->addTest(new CppUnit::TestCaller<YapetFileTest>{
85 "should refuse to open existing file with insecure permissions",
86 &YapetFileTest::failToOpenExistingFileWithInsecurePermissions});
87 suiteOfTests->addTest(new CppUnit::TestCaller<YapetFileTest>{
88 "should open existing file", &YapetFileTest::openExistingFile});
89 suiteOfTests->addTest(new CppUnit::TestCaller<YapetFileTest>{
90 "should be forced to open file with insecure permissions",
91 &YapetFileTest::forceOpenExistingFileWithInsecurePermissions});
92 suiteOfTests->addTest(new CppUnit::TestCaller<YapetFileTest>{
93 "should get filename", &YapetFileTest::filename});
94
95 return suiteOfTests;
96 }
97
setUp()98 void setUp() { ::unlink(TEST_FILE); }
99
tearDown()100 void tearDown() { ::unlink(TEST_FILE); }
101
throwOnNonExisting()102 void throwOnNonExisting() {
103 YapetFileMock file{false, false};
104 CPPUNIT_ASSERT_THROW(file.open(), yapet::FileError);
105 }
106
createNewFile()107 void createNewFile() {
108 YapetFileMock file{true, false};
109 file.open();
110
111 CPPUNIT_ASSERT(yapet::hasSecurePermissions(TEST_FILE) == true);
112 }
113
failToOpenExistingFileWithInsecurePermissions()114 void failToOpenExistingFileWithInsecurePermissions() {
115 auto fd = ::open(TEST_FILE, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
116 if (fd == -1) {
117 throw std::runtime_error("Failure to create test file");
118 }
119 ::close(fd);
120
121 YapetFileMock file{false, true};
122 CPPUNIT_ASSERT_THROW(file.open(), yapet::FileInsecureError);
123 }
124
openExistingFile()125 void openExistingFile() {
126 auto fd = ::open(TEST_FILE, O_CREAT, S_IRUSR | S_IWUSR);
127 if (fd == -1) {
128 throw std::runtime_error("Failure to create test file");
129 }
130 ::close(fd);
131
132 YapetFileMock file{false, true};
133 file.open();
134 // Not throwing is the test
135 }
136
forceOpenExistingFileWithInsecurePermissions()137 void forceOpenExistingFileWithInsecurePermissions() {
138 auto fd = ::open(TEST_FILE, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
139 if (fd == -1) {
140 throw std::runtime_error("Failure to create test file");
141 }
142 ::close(fd);
143
144 YapetFileMock file{false, false};
145 file.open();
146 // Not throwing is the test
147 }
148
filename()149 void filename() {
150 YapetFileMock file{false, true};
151
152 std::string expected{TEST_FILE};
153
154 CPPUNIT_ASSERT_EQUAL(expected, file.filename());
155 }
156 };
157
main()158 int main() {
159 CppUnit::TextUi::TestRunner runner;
160 runner.addTest(YapetFileTest::suite());
161 return runner.run() ? 0 : 1;
162 }