Apply clang-format
This commit is contained in:
parent
d4bb111800
commit
29220159fa
|
@ -42,3 +42,6 @@ Makefile*
|
||||||
|
|
||||||
# tests
|
# tests
|
||||||
*.backup
|
*.backup
|
||||||
|
|
||||||
|
# clang-format
|
||||||
|
/.clang-format
|
||||||
|
|
8
global.h
8
global.h
|
@ -7,11 +7,11 @@
|
||||||
#include <c++utilities/application/global.h>
|
#include <c++utilities/application/global.h>
|
||||||
|
|
||||||
#ifdef PASSWORD_FILE_STATIC
|
#ifdef PASSWORD_FILE_STATIC
|
||||||
# define PASSWORD_FILE_EXPORT
|
#define PASSWORD_FILE_EXPORT
|
||||||
# define PASSWORD_FILE_IMPORT
|
#define PASSWORD_FILE_IMPORT
|
||||||
#else
|
#else
|
||||||
# define PASSWORD_FILE_EXPORT LIB_EXPORT
|
#define PASSWORD_FILE_EXPORT LIB_EXPORT
|
||||||
# define PASSWORD_FILE_IMPORT LIB_IMPORT
|
#define PASSWORD_FILE_IMPORT LIB_IMPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -9,14 +9,14 @@ namespace Io {
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a crypto exception.
|
* \brief Constructs a crypto exception.
|
||||||
*/
|
*/
|
||||||
CryptoException::CryptoException(const std::string &openSslErrorQueue) USE_NOTHROW :
|
CryptoException::CryptoException(const std::string &openSslErrorQueue) USE_NOTHROW : runtime_error(openSslErrorQueue)
|
||||||
runtime_error(openSslErrorQueue)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Destroys the exception.
|
* \brief Destroys the exception.
|
||||||
*/
|
*/
|
||||||
CryptoException::~CryptoException() USE_NOTHROW
|
CryptoException::~CryptoException() USE_NOTHROW
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
|
|
||||||
namespace Io {
|
namespace Io {
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT CryptoException : public std::runtime_error
|
class PASSWORD_FILE_EXPORT CryptoException : public std::runtime_error {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
CryptoException(const std::string &openSslErrorQueue) USE_NOTHROW;
|
CryptoException(const std::string &openSslErrorQueue) USE_NOTHROW;
|
||||||
virtual ~CryptoException() USE_NOTHROW;
|
virtual ~CryptoException() USE_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CRYPTOFAILUREEXCEPTION_H
|
#endif // CRYPTOFAILUREEXCEPTION_H
|
||||||
|
|
152
io/entry.cpp
152
io/entry.cpp
|
@ -4,8 +4,8 @@
|
||||||
#include <c++utilities/io/binaryreader.h>
|
#include <c++utilities/io/binaryreader.h>
|
||||||
#include <c++utilities/io/binarywriter.h>
|
#include <c++utilities/io/binarywriter.h>
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace IoUtilities;
|
using namespace IoUtilities;
|
||||||
|
@ -29,9 +29,9 @@ namespace Io {
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new entry with the specified \a label and \a parent.
|
* \brief Constructs a new entry with the specified \a label and \a parent.
|
||||||
*/
|
*/
|
||||||
Entry::Entry(const string &label, NodeEntry *parent) :
|
Entry::Entry(const string &label, NodeEntry *parent)
|
||||||
m_parent(nullptr),
|
: m_parent(nullptr)
|
||||||
m_index(-1)
|
, m_index(-1)
|
||||||
{
|
{
|
||||||
setParent(parent);
|
setParent(parent);
|
||||||
setLabel(label);
|
setLabel(label);
|
||||||
|
@ -42,11 +42,12 @@ Entry::Entry(const string &label, NodeEntry *parent) :
|
||||||
* \remarks The copy will be parentless and thus not be embedded in the hierarchy
|
* \remarks The copy will be parentless and thus not be embedded in the hierarchy
|
||||||
* of \a other. Child entries will be copied as well.
|
* of \a other. Child entries will be copied as well.
|
||||||
*/
|
*/
|
||||||
Entry::Entry(const Entry &other) :
|
Entry::Entry(const Entry &other)
|
||||||
m_label(other.m_label),
|
: m_label(other.m_label)
|
||||||
m_parent(nullptr),
|
, m_parent(nullptr)
|
||||||
m_index(-1)
|
, m_index(-1)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Destroys the entry.
|
* \brief Destroys the entry.
|
||||||
|
@ -62,15 +63,15 @@ Entry::~Entry()
|
||||||
*/
|
*/
|
||||||
void Entry::makeLabelUnique()
|
void Entry::makeLabelUnique()
|
||||||
{
|
{
|
||||||
if(m_parent) {
|
if (m_parent) {
|
||||||
int index = 1;
|
int index = 1;
|
||||||
string currentLabel(label());
|
string currentLabel(label());
|
||||||
checkLabel:
|
checkLabel:
|
||||||
for(Entry *sibling : m_parent->children()) {
|
for (Entry *sibling : m_parent->children()) {
|
||||||
if(sibling != this && currentLabel == sibling->label()) {
|
if (sibling != this && currentLabel == sibling->label()) {
|
||||||
stringstream newLabel(currentLabel);
|
stringstream newLabel(currentLabel);
|
||||||
newLabel.seekp(0, ios_base::end);
|
newLabel.seekp(0, ios_base::end);
|
||||||
if(newLabel.tellp()) {
|
if (newLabel.tellp()) {
|
||||||
newLabel << ' ';
|
newLabel << ' ';
|
||||||
}
|
}
|
||||||
newLabel << ++index;
|
newLabel << ++index;
|
||||||
|
@ -90,20 +91,19 @@ void Entry::makeLabelUnique()
|
||||||
*/
|
*/
|
||||||
void Entry::setParent(NodeEntry *parent, int index)
|
void Entry::setParent(NodeEntry *parent, int index)
|
||||||
{
|
{
|
||||||
if(m_parent != parent || (m_index != index && index >= 0)) {
|
if (m_parent != parent || (m_index != index && index >= 0)) {
|
||||||
if(m_parent) {
|
if (m_parent) {
|
||||||
m_parent->m_children.erase(m_parent->m_children.begin() + m_index);
|
m_parent->m_children.erase(m_parent->m_children.begin() + m_index);
|
||||||
for(auto i = m_parent->m_children.begin() + m_index; i < m_parent->m_children.end(); ++i) {
|
for (auto i = m_parent->m_children.begin() + m_index; i < m_parent->m_children.end(); ++i) {
|
||||||
(*i)->m_index -= 1;
|
(*i)->m_index -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(parent) {
|
if (parent) {
|
||||||
if(index < 0 || static_cast<size_t>(index) >= parent->m_children.size()) {
|
if (index < 0 || static_cast<size_t>(index) >= parent->m_children.size()) {
|
||||||
m_index = parent->m_children.size();
|
m_index = parent->m_children.size();
|
||||||
parent->m_children.push_back(this);
|
parent->m_children.push_back(this);
|
||||||
} else {
|
} else {
|
||||||
for(auto i = parent->m_children.insert(parent->m_children.begin() + index, this) + 1;
|
for (auto i = parent->m_children.insert(parent->m_children.begin() + index, this) + 1; i != parent->m_children.end(); ++i) {
|
||||||
i != parent->m_children.end(); ++i) {
|
|
||||||
(*i)->m_index += 1;
|
(*i)->m_index += 1;
|
||||||
}
|
}
|
||||||
m_index = index;
|
m_index = index;
|
||||||
|
@ -121,8 +121,8 @@ void Entry::setParent(NodeEntry *parent, int index)
|
||||||
*/
|
*/
|
||||||
bool Entry::isIndirectChildOf(NodeEntry *entry) const
|
bool Entry::isIndirectChildOf(NodeEntry *entry) const
|
||||||
{
|
{
|
||||||
if(parent()) {
|
if (parent()) {
|
||||||
if(parent() == entry) {
|
if (parent() == entry) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return parent()->isIndirectChildOf(entry);
|
return parent()->isIndirectChildOf(entry);
|
||||||
|
@ -147,7 +147,7 @@ std::list<string> Entry::path() const
|
||||||
*/
|
*/
|
||||||
void Entry::path(std::list<string> &res) const
|
void Entry::path(std::list<string> &res) const
|
||||||
{
|
{
|
||||||
if(m_parent) {
|
if (m_parent) {
|
||||||
m_parent->path(res);
|
m_parent->path(res);
|
||||||
}
|
}
|
||||||
res.push_back(label());
|
res.push_back(label());
|
||||||
|
@ -160,7 +160,7 @@ void Entry::path(std::list<string> &res) const
|
||||||
Entry *Entry::parse(istream &stream)
|
Entry *Entry::parse(istream &stream)
|
||||||
{
|
{
|
||||||
byte version = stream.peek();
|
byte version = stream.peek();
|
||||||
if(denotesNodeEntry(version)) {
|
if (denotesNodeEntry(version)) {
|
||||||
return new NodeEntry(stream);
|
return new NodeEntry(stream);
|
||||||
} else {
|
} else {
|
||||||
return new AccountEntry(stream);
|
return new AccountEntry(stream);
|
||||||
|
@ -192,33 +192,35 @@ Entry *Entry::parse(istream &stream)
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new node entry.
|
* \brief Constructs a new node entry.
|
||||||
*/
|
*/
|
||||||
NodeEntry::NodeEntry() :
|
NodeEntry::NodeEntry()
|
||||||
Entry(),
|
: Entry()
|
||||||
m_expandedByDefault(true)
|
, m_expandedByDefault(true)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new node entry with the specified \a label and \a parent.
|
* \brief Constructs a new node entry with the specified \a label and \a parent.
|
||||||
*/
|
*/
|
||||||
NodeEntry::NodeEntry(const string &label, NodeEntry *parent) :
|
NodeEntry::NodeEntry(const string &label, NodeEntry *parent)
|
||||||
Entry(label, parent),
|
: Entry(label, parent)
|
||||||
m_expandedByDefault(true)
|
, m_expandedByDefault(true)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new node entry which is deserialized from the specified \a stream.
|
* \brief Constructs a new node entry which is deserialized from the specified \a stream.
|
||||||
*/
|
*/
|
||||||
NodeEntry::NodeEntry(istream &stream) :
|
NodeEntry::NodeEntry(istream &stream)
|
||||||
m_expandedByDefault(true)
|
: m_expandedByDefault(true)
|
||||||
{
|
{
|
||||||
BinaryReader reader(&stream);
|
BinaryReader reader(&stream);
|
||||||
byte version = reader.readByte();
|
byte version = reader.readByte();
|
||||||
if(denotesNodeEntry(version)) {
|
if (denotesNodeEntry(version)) {
|
||||||
if(version == 0x0 || version == 0x1) {
|
if (version == 0x0 || version == 0x1) {
|
||||||
setLabel(reader.readLengthPrefixedString());
|
setLabel(reader.readLengthPrefixedString());
|
||||||
if(version == 0x1) { // version 0x1 has an extended header
|
if (version == 0x1) { // version 0x1 has an extended header
|
||||||
uint16 extendedHeaderSize = reader.readUInt16BE();
|
uint16 extendedHeaderSize = reader.readUInt16BE();
|
||||||
if(extendedHeaderSize >= 1) {
|
if (extendedHeaderSize >= 1) {
|
||||||
byte flags = reader.readByte();
|
byte flags = reader.readByte();
|
||||||
m_expandedByDefault = flags & 0x80;
|
m_expandedByDefault = flags & 0x80;
|
||||||
extendedHeaderSize -= 1;
|
extendedHeaderSize -= 1;
|
||||||
|
@ -226,7 +228,7 @@ NodeEntry::NodeEntry(istream &stream) :
|
||||||
m_extendedData = reader.readString(extendedHeaderSize);
|
m_extendedData = reader.readString(extendedHeaderSize);
|
||||||
}
|
}
|
||||||
uint32 childCount = reader.readUInt32BE();
|
uint32 childCount = reader.readUInt32BE();
|
||||||
for(uint32 i = 0; i < childCount; ++i) {
|
for (uint32 i = 0; i < childCount; ++i) {
|
||||||
Entry::parse(stream)->setParent(this);
|
Entry::parse(stream)->setParent(this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -242,10 +244,10 @@ NodeEntry::NodeEntry(istream &stream) :
|
||||||
* \remarks The copy will be parentless and thus not be embedded in the hierarchy
|
* \remarks The copy will be parentless and thus not be embedded in the hierarchy
|
||||||
* of \a other. Child entries will be copied as well.
|
* of \a other. Child entries will be copied as well.
|
||||||
*/
|
*/
|
||||||
NodeEntry::NodeEntry(const NodeEntry &other) :
|
NodeEntry::NodeEntry(const NodeEntry &other)
|
||||||
Entry(other)
|
: Entry(other)
|
||||||
{
|
{
|
||||||
for(Entry *otherChild : other.m_children) {
|
for (Entry *otherChild : other.m_children) {
|
||||||
Entry *clonedChild = otherChild->clone();
|
Entry *clonedChild = otherChild->clone();
|
||||||
clonedChild->m_parent = this;
|
clonedChild->m_parent = this;
|
||||||
clonedChild->m_index = m_children.size();
|
clonedChild->m_index = m_children.size();
|
||||||
|
@ -258,7 +260,7 @@ NodeEntry::NodeEntry(const NodeEntry &other) :
|
||||||
*/
|
*/
|
||||||
NodeEntry::~NodeEntry()
|
NodeEntry::~NodeEntry()
|
||||||
{
|
{
|
||||||
for(Entry *child : m_children) {
|
for (Entry *child : m_children) {
|
||||||
child->m_parent = nullptr;
|
child->m_parent = nullptr;
|
||||||
delete child;
|
delete child;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +275,7 @@ void NodeEntry::deleteChildren(int begin, int end)
|
||||||
{
|
{
|
||||||
auto iterator = m_children.cbegin() + begin;
|
auto iterator = m_children.cbegin() + begin;
|
||||||
auto endIterator = m_children.begin() + end;
|
auto endIterator = m_children.begin() + end;
|
||||||
for(; iterator < endIterator; ++iterator) {
|
for (; iterator < endIterator; ++iterator) {
|
||||||
(*iterator)->m_parent = nullptr;
|
(*iterator)->m_parent = nullptr;
|
||||||
delete *iterator;
|
delete *iterator;
|
||||||
}
|
}
|
||||||
|
@ -285,7 +287,7 @@ void NodeEntry::deleteChildren(int begin, int end)
|
||||||
*/
|
*/
|
||||||
void NodeEntry::replaceChild(size_t at, Entry *newChild)
|
void NodeEntry::replaceChild(size_t at, Entry *newChild)
|
||||||
{
|
{
|
||||||
if(at < m_children.size()) {
|
if (at < m_children.size()) {
|
||||||
m_children.at(at)->m_parent = nullptr;
|
m_children.at(at)->m_parent = nullptr;
|
||||||
m_children[at] = newChild;
|
m_children[at] = newChild;
|
||||||
}
|
}
|
||||||
|
@ -302,30 +304,30 @@ void NodeEntry::replaceChild(size_t at, Entry *newChild)
|
||||||
*/
|
*/
|
||||||
Entry *NodeEntry::entryByPath(list<string> &path, bool includeThis, EntryType *creationType)
|
Entry *NodeEntry::entryByPath(list<string> &path, bool includeThis, EntryType *creationType)
|
||||||
{
|
{
|
||||||
if(path.size()) {
|
if (path.size()) {
|
||||||
if(includeThis) {
|
if (includeThis) {
|
||||||
if(path.front() == label()) {
|
if (path.front() == label()) {
|
||||||
path.pop_front();
|
path.pop_front();
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(path.size()) {
|
if (path.size()) {
|
||||||
for(Entry *child : m_children) {
|
for (Entry *child : m_children) {
|
||||||
if(path.front() == child->label()) {
|
if (path.front() == child->label()) {
|
||||||
path.pop_front();
|
path.pop_front();
|
||||||
if(path.empty()) {
|
if (path.empty()) {
|
||||||
return child;
|
return child;
|
||||||
} else if(child->type() == EntryType::Node) {
|
} else if (child->type() == EntryType::Node) {
|
||||||
return static_cast<NodeEntry *>(child)->entryByPath(path, false, creationType);
|
return static_cast<NodeEntry *>(child)->entryByPath(path, false, creationType);
|
||||||
} else {
|
} else {
|
||||||
return nullptr; // can not resolve path since an account entry can not have children
|
return nullptr; // can not resolve path since an account entry can not have children
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(creationType) {
|
if (creationType) {
|
||||||
if(path.size() == 1) {
|
if (path.size() == 1) {
|
||||||
switch(*creationType) {
|
switch (*creationType) {
|
||||||
case EntryType::Account:
|
case EntryType::Account:
|
||||||
return new AccountEntry(path.front(), this);
|
return new AccountEntry(path.front(), this);
|
||||||
case EntryType::Node:
|
case EntryType::Node:
|
||||||
|
@ -347,17 +349,17 @@ void NodeEntry::make(ostream &stream) const
|
||||||
BinaryWriter writer(&stream);
|
BinaryWriter writer(&stream);
|
||||||
writer.writeByte(isExpandedByDefault() && m_extendedData.empty() ? 0x0 : 0x1); // version
|
writer.writeByte(isExpandedByDefault() && m_extendedData.empty() ? 0x0 : 0x1); // version
|
||||||
writer.writeLengthPrefixedString(label());
|
writer.writeLengthPrefixedString(label());
|
||||||
if(!isExpandedByDefault() || !m_extendedData.empty()) {
|
if (!isExpandedByDefault() || !m_extendedData.empty()) {
|
||||||
writer.writeUInt16BE(1 + m_extendedData.size()); // extended header is 1 byte long
|
writer.writeUInt16BE(1 + m_extendedData.size()); // extended header is 1 byte long
|
||||||
byte flags = 0x00;
|
byte flags = 0x00;
|
||||||
if(isExpandedByDefault()) {
|
if (isExpandedByDefault()) {
|
||||||
flags |= 0x80;
|
flags |= 0x80;
|
||||||
}
|
}
|
||||||
writer.writeByte(flags);
|
writer.writeByte(flags);
|
||||||
writer.writeString(m_extendedData);
|
writer.writeString(m_extendedData);
|
||||||
}
|
}
|
||||||
writer.writeUInt32BE(m_children.size());
|
writer.writeUInt32BE(m_children.size());
|
||||||
for(const Entry *child : m_children) {
|
for (const Entry *child : m_children) {
|
||||||
child->make(stream);
|
child->make(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,14 +375,16 @@ NodeEntry *NodeEntry::clone() const
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AccountEntry::AccountEntry()
|
AccountEntry::AccountEntry()
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new account entry with the specified \a label and \a parent.
|
* \brief Constructs a new account entry with the specified \a label and \a parent.
|
||||||
*/
|
*/
|
||||||
AccountEntry::AccountEntry(const string &label, NodeEntry *parent) :
|
AccountEntry::AccountEntry(const string &label, NodeEntry *parent)
|
||||||
Entry(label, parent)
|
: Entry(label, parent)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new account entry which is deserialized from the specified \a stream.
|
* \brief Constructs a new account entry which is deserialized from the specified \a stream.
|
||||||
|
@ -389,17 +393,17 @@ AccountEntry::AccountEntry(istream &stream)
|
||||||
{
|
{
|
||||||
BinaryReader reader(&stream);
|
BinaryReader reader(&stream);
|
||||||
byte version = reader.readByte();
|
byte version = reader.readByte();
|
||||||
if(!denotesNodeEntry(version)) {
|
if (!denotesNodeEntry(version)) {
|
||||||
version ^= 0x80; // set bit 0 to false
|
version ^= 0x80; // set bit 0 to false
|
||||||
if(version == 0x0 || version == 0x1) {
|
if (version == 0x0 || version == 0x1) {
|
||||||
setLabel(reader.readLengthPrefixedString());
|
setLabel(reader.readLengthPrefixedString());
|
||||||
if(version == 0x1) { // version 0x1 has an extended header
|
if (version == 0x1) { // version 0x1 has an extended header
|
||||||
uint16 extendedHeaderSize = reader.readUInt16BE();
|
uint16 extendedHeaderSize = reader.readUInt16BE();
|
||||||
// currently there's nothing to read here
|
// currently there's nothing to read here
|
||||||
m_extendedData = reader.readString(extendedHeaderSize);
|
m_extendedData = reader.readString(extendedHeaderSize);
|
||||||
}
|
}
|
||||||
uint32 fieldCount = reader.readUInt32BE();
|
uint32 fieldCount = reader.readUInt32BE();
|
||||||
for(uint32 i = 0; i < fieldCount; ++i) {
|
for (uint32 i = 0; i < fieldCount; ++i) {
|
||||||
m_fields.push_back(Field(this, stream));
|
m_fields.push_back(Field(this, stream));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -415,8 +419,8 @@ AccountEntry::AccountEntry(istream &stream)
|
||||||
* \remarks The copy will be parentless and thus not be embedded in the hierarchy
|
* \remarks The copy will be parentless and thus not be embedded in the hierarchy
|
||||||
* of \a other. Child entries will be copied as well.
|
* of \a other. Child entries will be copied as well.
|
||||||
*/
|
*/
|
||||||
AccountEntry::AccountEntry(const AccountEntry &other) :
|
AccountEntry::AccountEntry(const AccountEntry &other)
|
||||||
Entry(other)
|
: Entry(other)
|
||||||
{
|
{
|
||||||
m_fields = other.m_fields;
|
m_fields = other.m_fields;
|
||||||
}
|
}
|
||||||
|
@ -425,19 +429,20 @@ AccountEntry::AccountEntry(const AccountEntry &other) :
|
||||||
* \brief Destroys the entry.
|
* \brief Destroys the entry.
|
||||||
*/
|
*/
|
||||||
AccountEntry::~AccountEntry()
|
AccountEntry::~AccountEntry()
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void AccountEntry::make(ostream &stream) const
|
void AccountEntry::make(ostream &stream) const
|
||||||
{
|
{
|
||||||
BinaryWriter writer(&stream);
|
BinaryWriter writer(&stream);
|
||||||
writer.writeByte(0x80 | (m_extendedData.empty() ? 0x0 : 0x1)); // version
|
writer.writeByte(0x80 | (m_extendedData.empty() ? 0x0 : 0x1)); // version
|
||||||
writer.writeLengthPrefixedString(label());
|
writer.writeLengthPrefixedString(label());
|
||||||
if(!m_extendedData.empty()) {
|
if (!m_extendedData.empty()) {
|
||||||
writer.writeUInt16BE(m_extendedData.size());
|
writer.writeUInt16BE(m_extendedData.size());
|
||||||
writer.writeString(m_extendedData);
|
writer.writeString(m_extendedData);
|
||||||
}
|
}
|
||||||
writer.writeUInt32BE(m_fields.size());
|
writer.writeUInt32BE(m_fields.size());
|
||||||
for(const Field &field : m_fields) {
|
for (const Field &field : m_fields) {
|
||||||
field.make(stream);
|
field.make(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,5 +451,4 @@ AccountEntry *AccountEntry::clone() const
|
||||||
{
|
{
|
||||||
return new AccountEntry(*this);
|
return new AccountEntry(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
19
io/entry.h
19
io/entry.h
|
@ -6,26 +6,25 @@
|
||||||
#include <c++utilities/conversion/types.h>
|
#include <c++utilities/conversion/types.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
namespace Io {
|
namespace Io {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Specifies the entry type.
|
* \brief Specifies the entry type.
|
||||||
*/
|
*/
|
||||||
enum class EntryType : int
|
enum class EntryType : int {
|
||||||
{
|
|
||||||
Node, /**< denotes a NodeEntry */
|
Node, /**< denotes a NodeEntry */
|
||||||
Account /**< denotes an AccountEntry */
|
Account /**< denotes an AccountEntry */
|
||||||
};
|
};
|
||||||
|
|
||||||
class NodeEntry;
|
class NodeEntry;
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT Entry
|
class PASSWORD_FILE_EXPORT Entry {
|
||||||
{
|
|
||||||
friend class NodeEntry;
|
friend class NodeEntry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Entry();
|
virtual ~Entry();
|
||||||
Entry &operator=(const Entry &other) = delete;
|
Entry &operator=(const Entry &other) = delete;
|
||||||
|
@ -55,7 +54,6 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_extendedData;
|
std::string m_extendedData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -94,9 +92,9 @@ inline int Entry::index() const
|
||||||
return m_index;
|
return m_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT NodeEntry : public Entry
|
class PASSWORD_FILE_EXPORT NodeEntry : public Entry {
|
||||||
{
|
|
||||||
friend class Entry;
|
friend class Entry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeEntry();
|
NodeEntry();
|
||||||
NodeEntry(const std::string &label, NodeEntry *parent = nullptr);
|
NodeEntry(const std::string &label, NodeEntry *parent = nullptr);
|
||||||
|
@ -144,8 +142,7 @@ inline bool Entry::denotesNodeEntry(byte version)
|
||||||
return (version & 0x80) == 0;
|
return (version & 0x80) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT AccountEntry : public Entry
|
class PASSWORD_FILE_EXPORT AccountEntry : public Entry {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
AccountEntry();
|
AccountEntry();
|
||||||
AccountEntry(const std::string &label, NodeEntry *parent = nullptr);
|
AccountEntry(const std::string &label, NodeEntry *parent = nullptr);
|
||||||
|
@ -158,6 +155,7 @@ public:
|
||||||
std::vector<Field> &fields();
|
std::vector<Field> &fields();
|
||||||
virtual void make(std::ostream &stream) const;
|
virtual void make(std::ostream &stream) const;
|
||||||
virtual AccountEntry *clone() const;
|
virtual AccountEntry *clone() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Field> m_fields;
|
std::vector<Field> m_fields;
|
||||||
};
|
};
|
||||||
|
@ -176,7 +174,6 @@ inline std::vector<Field> &AccountEntry::fields()
|
||||||
{
|
{
|
||||||
return m_fields;
|
return m_fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ENTRY_H
|
#endif // ENTRY_H
|
||||||
|
|
22
io/field.cpp
22
io/field.cpp
|
@ -20,12 +20,13 @@ namespace Io {
|
||||||
* \brief Constructs a new account entry for the specified account with the specified \a name
|
* \brief Constructs a new account entry for the specified account with the specified \a name
|
||||||
* and \a value.
|
* and \a value.
|
||||||
*/
|
*/
|
||||||
Field::Field(AccountEntry *tiedAccount, const string &name, const string &value) :
|
Field::Field(AccountEntry *tiedAccount, const string &name, const string &value)
|
||||||
m_name(name),
|
: m_name(name)
|
||||||
m_value(value),
|
, m_value(value)
|
||||||
m_type(FieldType::Normal),
|
, m_type(FieldType::Normal)
|
||||||
m_tiedAccount(tiedAccount)
|
, m_tiedAccount(tiedAccount)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new account entry for the specified account which is deserialize from
|
* \brief Constructs a new account entry for the specified account which is deserialize from
|
||||||
|
@ -36,16 +37,16 @@ Field::Field(AccountEntry *tiedAccount, istream &stream)
|
||||||
{
|
{
|
||||||
BinaryReader reader(&stream);
|
BinaryReader reader(&stream);
|
||||||
int version = reader.readByte();
|
int version = reader.readByte();
|
||||||
if(version == 0x0 || version == 0x1) {
|
if (version == 0x0 || version == 0x1) {
|
||||||
m_name = reader.readLengthPrefixedString();
|
m_name = reader.readLengthPrefixedString();
|
||||||
m_value = reader.readLengthPrefixedString();
|
m_value = reader.readLengthPrefixedString();
|
||||||
byte type = reader.readByte();
|
byte type = reader.readByte();
|
||||||
if(isValidType(type)) {
|
if (isValidType(type)) {
|
||||||
m_type = static_cast<FieldType>(type);
|
m_type = static_cast<FieldType>(type);
|
||||||
} else {
|
} else {
|
||||||
throw ParsingException("Field type is not supported.");
|
throw ParsingException("Field type is not supported.");
|
||||||
}
|
}
|
||||||
if(version == 0x1) { // version 0x1 has an extended header
|
if (version == 0x1) { // version 0x1 has an extended header
|
||||||
uint16 extendedHeaderSize = reader.readUInt16BE();
|
uint16 extendedHeaderSize = reader.readUInt16BE();
|
||||||
// currently there's nothing to read here
|
// currently there's nothing to read here
|
||||||
m_extendedData = reader.readString(extendedHeaderSize);
|
m_extendedData = reader.readString(extendedHeaderSize);
|
||||||
|
@ -66,10 +67,9 @@ void Field::make(ostream &stream) const
|
||||||
writer.writeLengthPrefixedString(m_name);
|
writer.writeLengthPrefixedString(m_name);
|
||||||
writer.writeLengthPrefixedString(m_value);
|
writer.writeLengthPrefixedString(m_value);
|
||||||
writer.writeByte(static_cast<byte>(m_type));
|
writer.writeByte(static_cast<byte>(m_type));
|
||||||
if(!m_extendedData.empty()) {
|
if (!m_extendedData.empty()) {
|
||||||
writer.writeUInt16BE(m_extendedData.size());
|
writer.writeUInt16BE(m_extendedData.size());
|
||||||
writer.writeString(m_extendedData);
|
writer.writeString(m_extendedData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
11
io/field.h
11
io/field.h
|
@ -8,16 +8,11 @@
|
||||||
|
|
||||||
namespace Io {
|
namespace Io {
|
||||||
|
|
||||||
enum class FieldType : int
|
enum class FieldType : int { Normal, Password };
|
||||||
{
|
|
||||||
Normal,
|
|
||||||
Password
|
|
||||||
};
|
|
||||||
|
|
||||||
class AccountEntry;
|
class AccountEntry;
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT Field
|
class PASSWORD_FILE_EXPORT Field {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Field(AccountEntry *tiedAccount, const std::string &name = std::string(), const std::string &value = std::string());
|
Field(AccountEntry *tiedAccount, const std::string &name = std::string(), const std::string &value = std::string());
|
||||||
Field(AccountEntry *tiedAccount, std::istream &stream);
|
Field(AccountEntry *tiedAccount, std::istream &stream);
|
||||||
|
@ -41,7 +36,6 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string m_extendedData;
|
std::string m_extendedData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -115,7 +109,6 @@ inline bool Field::isValidType(int number)
|
||||||
{
|
{
|
||||||
return number >= 0 && number <= 1;
|
return number >= 0 && number <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FIELD_H
|
#endif // FIELD_H
|
||||||
|
|
|
@ -10,14 +10,14 @@ namespace Io {
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a parsing exception.
|
* \brief Constructs a parsing exception.
|
||||||
*/
|
*/
|
||||||
ParsingException::ParsingException(const std::string &message) USE_NOTHROW :
|
ParsingException::ParsingException(const std::string &message) USE_NOTHROW : runtime_error(message)
|
||||||
runtime_error(message)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Destroys the exception.
|
* \brief Destroys the exception.
|
||||||
*/
|
*/
|
||||||
ParsingException::~ParsingException() USE_NOTHROW
|
ParsingException::~ParsingException() USE_NOTHROW
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
|
|
||||||
namespace Io {
|
namespace Io {
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT ParsingException : public std::runtime_error
|
class PASSWORD_FILE_EXPORT ParsingException : public std::runtime_error {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ParsingException(const std::string &message = std::string()) USE_NOTHROW;
|
ParsingException(const std::string &message = std::string()) USE_NOTHROW;
|
||||||
virtual ~ParsingException() USE_NOTHROW;
|
virtual ~ParsingException() USE_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PARSINGEXCEPTION_H
|
#endif // PARSINGEXCEPTION_H
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "./passwordfile.h"
|
#include "./passwordfile.h"
|
||||||
#include "./cryptoexception.h"
|
#include "./cryptoexception.h"
|
||||||
#include "./parsingexception.h"
|
|
||||||
#include "./entry.h"
|
#include "./entry.h"
|
||||||
|
#include "./parsingexception.h"
|
||||||
|
|
||||||
#include <c++utilities/io/catchiofailure.h>
|
#include <c++utilities/io/catchiofailure.h>
|
||||||
|
|
||||||
|
@ -12,11 +12,11 @@
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#include <streambuf>
|
|
||||||
#include <sstream>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <streambuf>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace IoUtilities;
|
using namespace IoUtilities;
|
||||||
|
@ -34,9 +34,9 @@ const unsigned int aes256cbcIvSize = 16U;
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new password file.
|
* \brief Constructs a new password file.
|
||||||
*/
|
*/
|
||||||
PasswordFile::PasswordFile() :
|
PasswordFile::PasswordFile()
|
||||||
m_freader(BinaryReader(&m_file)),
|
: m_freader(BinaryReader(&m_file))
|
||||||
m_fwriter(BinaryWriter(&m_file))
|
, m_fwriter(BinaryWriter(&m_file))
|
||||||
{
|
{
|
||||||
m_file.exceptions(ios_base::failbit | ios_base::badbit);
|
m_file.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
clearPassword();
|
clearPassword();
|
||||||
|
@ -45,9 +45,9 @@ PasswordFile::PasswordFile() :
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a new password file with the specified \a path and \a password.
|
* \brief Constructs a new password file with the specified \a path and \a password.
|
||||||
*/
|
*/
|
||||||
PasswordFile::PasswordFile(const string &path, const string &password) :
|
PasswordFile::PasswordFile(const string &path, const string &password)
|
||||||
m_freader(BinaryReader(&m_file)),
|
: m_freader(BinaryReader(&m_file))
|
||||||
m_fwriter(BinaryWriter(&m_file))
|
, m_fwriter(BinaryWriter(&m_file))
|
||||||
{
|
{
|
||||||
m_file.exceptions(ios_base::failbit | ios_base::badbit);
|
m_file.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
setPath(path);
|
setPath(path);
|
||||||
|
@ -57,10 +57,10 @@ PasswordFile::PasswordFile(const string &path, const string &password) :
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructs a copy of another password file.
|
* \brief Constructs a copy of another password file.
|
||||||
*/
|
*/
|
||||||
PasswordFile::PasswordFile(const PasswordFile &other) :
|
PasswordFile::PasswordFile(const PasswordFile &other)
|
||||||
m_path(other.m_path),
|
: m_path(other.m_path)
|
||||||
m_freader(BinaryReader(&m_file)),
|
, m_freader(BinaryReader(&m_file))
|
||||||
m_fwriter(BinaryWriter(&m_file))
|
, m_fwriter(BinaryWriter(&m_file))
|
||||||
{
|
{
|
||||||
m_file.exceptions(ios_base::failbit | ios_base::badbit);
|
m_file.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
setPath(other.path());
|
setPath(other.path());
|
||||||
|
@ -82,12 +82,12 @@ PasswordFile::~PasswordFile()
|
||||||
void PasswordFile::open(bool readOnly)
|
void PasswordFile::open(bool readOnly)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
if(m_path.empty()) {
|
if (m_path.empty()) {
|
||||||
throwIoFailure("Unable to open file because path is emtpy.");
|
throwIoFailure("Unable to open file because path is emtpy.");
|
||||||
}
|
}
|
||||||
m_file.open(m_path, readOnly ? ios_base::in | ios_base::binary : ios_base::in | ios_base::out | ios_base::binary);
|
m_file.open(m_path, readOnly ? ios_base::in | ios_base::binary : ios_base::in | ios_base::out | ios_base::binary);
|
||||||
m_file.seekg(0, ios_base::end);
|
m_file.seekg(0, ios_base::end);
|
||||||
if(m_file.tellg() == 0) {
|
if (m_file.tellg() == 0) {
|
||||||
throwIoFailure("File is empty.");
|
throwIoFailure("File is empty.");
|
||||||
} else {
|
} else {
|
||||||
m_file.seekg(0);
|
m_file.seekg(0);
|
||||||
|
@ -99,7 +99,7 @@ void PasswordFile::open(bool readOnly)
|
||||||
*/
|
*/
|
||||||
void PasswordFile::generateRootEntry()
|
void PasswordFile::generateRootEntry()
|
||||||
{
|
{
|
||||||
if(!m_rootEntry) {
|
if (!m_rootEntry) {
|
||||||
m_rootEntry.reset(new NodeEntry("accounts"));
|
m_rootEntry.reset(new NodeEntry("accounts"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ void PasswordFile::generateRootEntry()
|
||||||
void PasswordFile::create()
|
void PasswordFile::create()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
if(m_path.empty()) {
|
if (m_path.empty()) {
|
||||||
throwIoFailure("Unable to create file because path is empty.");
|
throwIoFailure("Unable to create file because path is empty.");
|
||||||
}
|
}
|
||||||
m_file.open(m_path, fstream::out | fstream::trunc | fstream::binary);
|
m_file.open(m_path, fstream::out | fstream::trunc | fstream::binary);
|
||||||
|
@ -127,23 +127,23 @@ void PasswordFile::create()
|
||||||
*/
|
*/
|
||||||
void PasswordFile::load()
|
void PasswordFile::load()
|
||||||
{
|
{
|
||||||
if(!m_file.is_open()) {
|
if (!m_file.is_open()) {
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
m_file.seekg(0);
|
m_file.seekg(0);
|
||||||
// check magic number
|
// check magic number
|
||||||
if(m_freader.readUInt32LE() != 0x7770616DU) {
|
if (m_freader.readUInt32LE() != 0x7770616DU) {
|
||||||
throw ParsingException("Signature not present.");
|
throw ParsingException("Signature not present.");
|
||||||
}
|
}
|
||||||
// check version and flags (used in version 0x3 only)
|
// check version and flags (used in version 0x3 only)
|
||||||
uint32 version = m_freader.readUInt32LE();
|
uint32 version = m_freader.readUInt32LE();
|
||||||
if(version != 0x0U && version != 0x1U && version != 0x2U && version != 0x3U && version != 0x4U && version != 0x5U) {
|
if (version != 0x0U && version != 0x1U && version != 0x2U && version != 0x3U && version != 0x4U && version != 0x5U) {
|
||||||
throw ParsingException("Version is unknown.");
|
throw ParsingException("Version is unknown.");
|
||||||
}
|
}
|
||||||
bool decrypterUsed;
|
bool decrypterUsed;
|
||||||
bool ivUsed;
|
bool ivUsed;
|
||||||
bool compressionUsed;
|
bool compressionUsed;
|
||||||
if(version == 0x3U) {
|
if (version == 0x3U) {
|
||||||
byte flags = m_freader.readByte();
|
byte flags = m_freader.readByte();
|
||||||
decrypterUsed = flags & 0x80;
|
decrypterUsed = flags & 0x80;
|
||||||
ivUsed = flags & 0x40;
|
ivUsed = flags & 0x40;
|
||||||
|
@ -156,7 +156,7 @@ void PasswordFile::load()
|
||||||
// skip extended header
|
// skip extended header
|
||||||
// the extended header might be used in further versions to
|
// the extended header might be used in further versions to
|
||||||
// add additional information without breaking compatibility
|
// add additional information without breaking compatibility
|
||||||
if(version >= 0x4U) {
|
if (version >= 0x4U) {
|
||||||
uint16 extendedHeaderSize = m_freader.readUInt16BE();
|
uint16 extendedHeaderSize = m_freader.readUInt16BE();
|
||||||
m_extendedHeader = m_freader.readString(extendedHeaderSize);
|
m_extendedHeader = m_freader.readString(extendedHeaderSize);
|
||||||
}
|
}
|
||||||
|
@ -167,37 +167,39 @@ void PasswordFile::load()
|
||||||
m_file.seekg(headerSize, ios_base::beg);
|
m_file.seekg(headerSize, ios_base::beg);
|
||||||
size -= headerSize;
|
size -= headerSize;
|
||||||
// read file
|
// read file
|
||||||
unsigned char iv[aes256cbcIvSize] = {0};
|
unsigned char iv[aes256cbcIvSize] = { 0 };
|
||||||
if(decrypterUsed && ivUsed) {
|
if (decrypterUsed && ivUsed) {
|
||||||
if(size < aes256cbcIvSize) {
|
if (size < aes256cbcIvSize) {
|
||||||
throw ParsingException("Initiation vector not present.");
|
throw ParsingException("Initiation vector not present.");
|
||||||
}
|
}
|
||||||
m_file.read(reinterpret_cast<char *>(iv), aes256cbcIvSize);
|
m_file.read(reinterpret_cast<char *>(iv), aes256cbcIvSize);
|
||||||
size -= aes256cbcIvSize;
|
size -= aes256cbcIvSize;
|
||||||
}
|
}
|
||||||
if(size <= 0) {
|
if (size <= 0) {
|
||||||
throw ParsingException("No contents found.");
|
throw ParsingException("No contents found.");
|
||||||
}
|
}
|
||||||
// decrypt contents
|
// decrypt contents
|
||||||
vector<char> rawbuff;
|
vector<char> rawbuff;
|
||||||
m_freader.read(rawbuff, size);
|
m_freader.read(rawbuff, size);
|
||||||
vector<char> decbuff;
|
vector<char> decbuff;
|
||||||
if(decrypterUsed) {
|
if (decrypterUsed) {
|
||||||
// initiate ctx
|
// initiate ctx
|
||||||
EVP_CIPHER_CTX *ctx = nullptr;
|
EVP_CIPHER_CTX *ctx = nullptr;
|
||||||
decbuff.resize(size + static_cast<fstream::pos_type>(32));
|
decbuff.resize(size + static_cast<fstream::pos_type>(32));
|
||||||
int outlen1, outlen2;
|
int outlen1, outlen2;
|
||||||
if ((ctx = EVP_CIPHER_CTX_new()) == nullptr
|
if ((ctx = EVP_CIPHER_CTX_new()) == nullptr
|
||||||
|| EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, reinterpret_cast<unsigned const char *>(m_password), iv) != 1
|
|| EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, reinterpret_cast<unsigned const char *>(m_password), iv) != 1
|
||||||
|| EVP_DecryptUpdate(ctx, reinterpret_cast<unsigned char *>(decbuff.data()), &outlen1, reinterpret_cast<unsigned char *>(rawbuff.data()), size) != 1
|
|| EVP_DecryptUpdate(
|
||||||
|| EVP_DecryptFinal_ex(ctx, reinterpret_cast<unsigned char *>(decbuff.data()) + outlen1, &outlen2) != 1) {
|
ctx, reinterpret_cast<unsigned char *>(decbuff.data()), &outlen1, reinterpret_cast<unsigned char *>(rawbuff.data()), size)
|
||||||
if(ctx) {
|
!= 1
|
||||||
|
|| EVP_DecryptFinal_ex(ctx, reinterpret_cast<unsigned char *>(decbuff.data()) + outlen1, &outlen2) != 1) {
|
||||||
|
if (ctx) {
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
string msg;
|
string msg;
|
||||||
unsigned long errorCode = ERR_get_error();
|
unsigned long errorCode = ERR_get_error();
|
||||||
while(errorCode != 0) {
|
while (errorCode != 0) {
|
||||||
if(!msg.empty()) {
|
if (!msg.empty()) {
|
||||||
msg += "\n";
|
msg += "\n";
|
||||||
}
|
}
|
||||||
msg += ERR_error_string(errorCode, 0);
|
msg += ERR_error_string(errorCode, 0);
|
||||||
|
@ -205,7 +207,7 @@ void PasswordFile::load()
|
||||||
}
|
}
|
||||||
throw CryptoException(msg);
|
throw CryptoException(msg);
|
||||||
} else { // decryption suceeded
|
} else { // decryption suceeded
|
||||||
if(ctx) {
|
if (ctx) {
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
size = outlen1 + outlen2;
|
size = outlen1 + outlen2;
|
||||||
|
@ -214,13 +216,14 @@ void PasswordFile::load()
|
||||||
decbuff.swap(rawbuff);
|
decbuff.swap(rawbuff);
|
||||||
}
|
}
|
||||||
// decompress
|
// decompress
|
||||||
if(compressionUsed) {
|
if (compressionUsed) {
|
||||||
if(size < 8) {
|
if (size < 8) {
|
||||||
throw ParsingException("File is truncated (decompressed size expected).");
|
throw ParsingException("File is truncated (decompressed size expected).");
|
||||||
}
|
}
|
||||||
uLongf decompressedSize = ConversionUtilities::LE::toUInt64(decbuff.data());
|
uLongf decompressedSize = ConversionUtilities::LE::toUInt64(decbuff.data());
|
||||||
rawbuff.resize(decompressedSize);
|
rawbuff.resize(decompressedSize);
|
||||||
switch(uncompress(reinterpret_cast<Bytef *>(rawbuff.data()), &decompressedSize, reinterpret_cast<Bytef *>(decbuff.data() + 8), size - static_cast<fstream::pos_type>(8))) {
|
switch (uncompress(reinterpret_cast<Bytef *>(rawbuff.data()), &decompressedSize, reinterpret_cast<Bytef *>(decbuff.data() + 8),
|
||||||
|
size - static_cast<fstream::pos_type>(8))) {
|
||||||
case Z_MEM_ERROR:
|
case Z_MEM_ERROR:
|
||||||
throw ParsingException("Decompressing failed. The source buffer was too small.");
|
throw ParsingException("Decompressing failed. The source buffer was too small.");
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
|
@ -237,7 +240,7 @@ void PasswordFile::load()
|
||||||
buffstr.write(decbuff.data(), static_cast<streamsize>(size));
|
buffstr.write(decbuff.data(), static_cast<streamsize>(size));
|
||||||
decbuff.resize(0);
|
decbuff.resize(0);
|
||||||
buffstr.seekg(0, ios_base::beg);
|
buffstr.seekg(0, ios_base::beg);
|
||||||
if(version >= 0x5u) {
|
if (version >= 0x5u) {
|
||||||
uint16 extendedHeaderSize = m_freader.readUInt16BE();
|
uint16 extendedHeaderSize = m_freader.readUInt16BE();
|
||||||
m_encryptedExtendedHeader = m_freader.readString(extendedHeaderSize);
|
m_encryptedExtendedHeader = m_freader.readString(extendedHeaderSize);
|
||||||
}
|
}
|
||||||
|
@ -254,11 +257,11 @@ void PasswordFile::load()
|
||||||
*/
|
*/
|
||||||
void PasswordFile::save(bool useEncryption, bool useCompression)
|
void PasswordFile::save(bool useEncryption, bool useCompression)
|
||||||
{
|
{
|
||||||
if(!m_rootEntry) {
|
if (!m_rootEntry) {
|
||||||
throw runtime_error("Root entry has not been created.");
|
throw runtime_error("Root entry has not been created.");
|
||||||
}
|
}
|
||||||
// open file
|
// open file
|
||||||
if(m_file.is_open()) {
|
if (m_file.is_open()) {
|
||||||
m_file.close();
|
m_file.close();
|
||||||
m_file.clear();
|
m_file.clear();
|
||||||
}
|
}
|
||||||
|
@ -268,15 +271,15 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
||||||
// write version, extended header requires version 4, encrypted extended header required version 5
|
// write version, extended header requires version 4, encrypted extended header required version 5
|
||||||
m_fwriter.writeUInt32LE(m_extendedHeader.empty() && m_encryptedExtendedHeader.empty() ? 0x3U : (m_encryptedExtendedHeader.empty() ? 0x4U : 0x5U));
|
m_fwriter.writeUInt32LE(m_extendedHeader.empty() && m_encryptedExtendedHeader.empty() ? 0x3U : (m_encryptedExtendedHeader.empty() ? 0x4U : 0x5U));
|
||||||
byte flags = 0x00;
|
byte flags = 0x00;
|
||||||
if(useEncryption) {
|
if (useEncryption) {
|
||||||
flags |= 0x80 | 0x40;
|
flags |= 0x80 | 0x40;
|
||||||
}
|
}
|
||||||
if(useCompression) {
|
if (useCompression) {
|
||||||
flags |= 0x20;
|
flags |= 0x20;
|
||||||
}
|
}
|
||||||
m_fwriter.writeByte(flags);
|
m_fwriter.writeByte(flags);
|
||||||
// write extened header
|
// write extened header
|
||||||
if(!m_extendedHeader.empty()) {
|
if (!m_extendedHeader.empty()) {
|
||||||
m_fwriter.writeUInt16BE(m_extendedHeader.size());
|
m_fwriter.writeUInt16BE(m_extendedHeader.size());
|
||||||
m_fwriter.writeString(m_extendedHeader);
|
m_fwriter.writeString(m_extendedHeader);
|
||||||
}
|
}
|
||||||
|
@ -284,7 +287,7 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
||||||
stringstream buffstr(stringstream::in | stringstream::out | stringstream::binary);
|
stringstream buffstr(stringstream::in | stringstream::out | stringstream::binary);
|
||||||
buffstr.exceptions(ios_base::failbit | ios_base::badbit);
|
buffstr.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
// write encrypted extened header
|
// write encrypted extened header
|
||||||
if(!m_encryptedExtendedHeader.empty()) {
|
if (!m_encryptedExtendedHeader.empty()) {
|
||||||
m_fwriter.writeUInt16BE(m_encryptedExtendedHeader.size());
|
m_fwriter.writeUInt16BE(m_encryptedExtendedHeader.size());
|
||||||
m_fwriter.writeString(m_encryptedExtendedHeader);
|
m_fwriter.writeString(m_encryptedExtendedHeader);
|
||||||
}
|
}
|
||||||
|
@ -297,11 +300,11 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
||||||
buffstr.read(decbuff.data(), size);
|
buffstr.read(decbuff.data(), size);
|
||||||
vector<char> encbuff;
|
vector<char> encbuff;
|
||||||
// compress data
|
// compress data
|
||||||
if(useCompression) {
|
if (useCompression) {
|
||||||
uLongf compressedSize = compressBound(size);
|
uLongf compressedSize = compressBound(size);
|
||||||
encbuff.resize(8 + compressedSize);
|
encbuff.resize(8 + compressedSize);
|
||||||
ConversionUtilities::LE::getBytes(static_cast<uint64>(size), encbuff.data());
|
ConversionUtilities::LE::getBytes(static_cast<uint64>(size), encbuff.data());
|
||||||
switch(compress(reinterpret_cast<Bytef *>(encbuff.data() + 8), &compressedSize, reinterpret_cast<Bytef *>(decbuff.data()), size)) {
|
switch (compress(reinterpret_cast<Bytef *>(encbuff.data() + 8), &compressedSize, reinterpret_cast<Bytef *>(decbuff.data()), size)) {
|
||||||
case Z_MEM_ERROR:
|
case Z_MEM_ERROR:
|
||||||
throw runtime_error("Decompressing failed. The source buffer was too small.");
|
throw runtime_error("Decompressing failed. The source buffer was too small.");
|
||||||
case Z_BUF_ERROR:
|
case Z_BUF_ERROR:
|
||||||
|
@ -312,24 +315,25 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// encrypt data
|
// encrypt data
|
||||||
if(useEncryption) {
|
if (useEncryption) {
|
||||||
// initiate ctx
|
// initiate ctx
|
||||||
EVP_CIPHER_CTX *ctx = nullptr;
|
EVP_CIPHER_CTX *ctx = nullptr;
|
||||||
unsigned char iv[aes256cbcIvSize];
|
unsigned char iv[aes256cbcIvSize];
|
||||||
int outlen1, outlen2;
|
int outlen1, outlen2;
|
||||||
encbuff.resize(size + static_cast<fstream::pos_type>(32));
|
encbuff.resize(size + static_cast<fstream::pos_type>(32));
|
||||||
if (RAND_bytes(iv, aes256cbcIvSize) != 1
|
if (RAND_bytes(iv, aes256cbcIvSize) != 1 || (ctx = EVP_CIPHER_CTX_new()) == nullptr
|
||||||
|| (ctx = EVP_CIPHER_CTX_new()) == nullptr
|
|| EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, reinterpret_cast<unsigned const char *>(m_password), iv) != 1
|
||||||
|| EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, reinterpret_cast<unsigned const char *>(m_password), iv) != 1
|
|| EVP_EncryptUpdate(
|
||||||
|| EVP_EncryptUpdate(ctx, reinterpret_cast<unsigned char *>(encbuff.data()), &outlen1, reinterpret_cast<unsigned char *>(decbuff.data()), size) != 1
|
ctx, reinterpret_cast<unsigned char *>(encbuff.data()), &outlen1, reinterpret_cast<unsigned char *>(decbuff.data()), size)
|
||||||
|| EVP_EncryptFinal_ex(ctx, reinterpret_cast<unsigned char *>(encbuff.data()) + outlen1, &outlen2) != 1) {
|
!= 1
|
||||||
if(ctx) {
|
|| EVP_EncryptFinal_ex(ctx, reinterpret_cast<unsigned char *>(encbuff.data()) + outlen1, &outlen2) != 1) {
|
||||||
|
if (ctx) {
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
string msg;
|
string msg;
|
||||||
unsigned long errorCode = ERR_get_error();
|
unsigned long errorCode = ERR_get_error();
|
||||||
while(errorCode != 0) {
|
while (errorCode != 0) {
|
||||||
if(!msg.empty()) {
|
if (!msg.empty()) {
|
||||||
msg += "\n";
|
msg += "\n";
|
||||||
}
|
}
|
||||||
msg += ERR_error_string(errorCode, 0);
|
msg += ERR_error_string(errorCode, 0);
|
||||||
|
@ -337,7 +341,7 @@ void PasswordFile::save(bool useEncryption, bool useCompression)
|
||||||
}
|
}
|
||||||
throw CryptoException(msg);
|
throw CryptoException(msg);
|
||||||
} else { // decryption succeeded
|
} else { // decryption succeeded
|
||||||
if(ctx) {
|
if (ctx) {
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
// write encrypted data to file
|
// write encrypted data to file
|
||||||
|
@ -380,30 +384,30 @@ void PasswordFile::clear()
|
||||||
*/
|
*/
|
||||||
void PasswordFile::exportToTextfile(const string &targetPath) const
|
void PasswordFile::exportToTextfile(const string &targetPath) const
|
||||||
{
|
{
|
||||||
if(!m_rootEntry) {
|
if (!m_rootEntry) {
|
||||||
throw runtime_error("Root entry has not been created.");
|
throw runtime_error("Root entry has not been created.");
|
||||||
}
|
}
|
||||||
fstream output(targetPath.c_str(), ios_base::out);
|
fstream output(targetPath.c_str(), ios_base::out);
|
||||||
function<void (int level)> indention = [&output] (int level) {
|
function<void(int level)> indention = [&output](int level) {
|
||||||
for(int i = 0; i < level; ++i) {
|
for (int i = 0; i < level; ++i) {
|
||||||
output << " ";
|
output << " ";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function<void (const Entry *entry, int level)> printNode;
|
function<void(const Entry *entry, int level)> printNode;
|
||||||
printNode = [&output, &printNode, &indention] (const Entry *entry, int level) {
|
printNode = [&output, &printNode, &indention](const Entry *entry, int level) {
|
||||||
indention(level);
|
indention(level);
|
||||||
output << " - " << entry->label() << endl;
|
output << " - " << entry->label() << endl;
|
||||||
switch(entry->type()) {
|
switch (entry->type()) {
|
||||||
case EntryType::Node:
|
case EntryType::Node:
|
||||||
for(const Entry *child : static_cast<const NodeEntry *>(entry)->children()) {
|
for (const Entry *child : static_cast<const NodeEntry *>(entry)->children()) {
|
||||||
printNode(child, level + 1);
|
printNode(child, level + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EntryType::Account:
|
case EntryType::Account:
|
||||||
for(const Field &field : static_cast<const AccountEntry *>(entry)->fields()) {
|
for (const Field &field : static_cast<const AccountEntry *>(entry)->fields()) {
|
||||||
indention(level);
|
indention(level);
|
||||||
output << " " << field.name();
|
output << " " << field.name();
|
||||||
for(int i = field.name().length(); i < 15; ++i) {
|
for (int i = field.name().length(); i < 15; ++i) {
|
||||||
output << ' ';
|
output << ' ';
|
||||||
}
|
}
|
||||||
output << field.value() << endl;
|
output << field.value() << endl;
|
||||||
|
@ -420,11 +424,11 @@ void PasswordFile::exportToTextfile(const string &targetPath) const
|
||||||
*/
|
*/
|
||||||
void PasswordFile::doBackup()
|
void PasswordFile::doBackup()
|
||||||
{
|
{
|
||||||
if(!isOpen()) {
|
if (!isOpen()) {
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
m_file.seekg(0, ios_base::end);
|
m_file.seekg(0, ios_base::end);
|
||||||
if(m_file.tellg()) {
|
if (m_file.tellg()) {
|
||||||
m_file.seekg(0);
|
m_file.seekg(0);
|
||||||
fstream backupFile(m_path + ".backup", ios::out | ios::trunc | ios::binary);
|
fstream backupFile(m_path + ".backup", ios::out | ios::trunc | ios::binary);
|
||||||
backupFile.exceptions(ios_base::failbit | ios_base::badbit);
|
backupFile.exceptions(ios_base::failbit | ios_base::badbit);
|
||||||
|
@ -466,7 +470,7 @@ NodeEntry *PasswordFile::rootEntry()
|
||||||
*/
|
*/
|
||||||
void PasswordFile::close()
|
void PasswordFile::close()
|
||||||
{
|
{
|
||||||
if(m_file.is_open()) {
|
if (m_file.is_open()) {
|
||||||
m_file.close();
|
m_file.close();
|
||||||
}
|
}
|
||||||
m_file.clear();
|
m_file.clear();
|
||||||
|
@ -528,19 +532,19 @@ void PasswordFile::clearPassword()
|
||||||
*/
|
*/
|
||||||
bool PasswordFile::isEncryptionUsed()
|
bool PasswordFile::isEncryptionUsed()
|
||||||
{
|
{
|
||||||
if(!isOpen()) {
|
if (!isOpen()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_file.seekg(0);
|
m_file.seekg(0);
|
||||||
//check magic number
|
//check magic number
|
||||||
if(m_freader.readUInt32LE() != 0x7770616DU) {
|
if (m_freader.readUInt32LE() != 0x7770616DU) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//check version
|
//check version
|
||||||
uint32 version = m_freader.readUInt32LE();
|
uint32 version = m_freader.readUInt32LE();
|
||||||
if(version == 0x1U || version == 0x2U) {
|
if (version == 0x1U || version == 0x2U) {
|
||||||
return true;
|
return true;
|
||||||
} else if(version == 0x3U) {
|
} else if (version == 0x3U) {
|
||||||
return m_freader.readByte() & 0x80;
|
return m_freader.readByte() & 0x80;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -560,11 +564,10 @@ bool PasswordFile::isOpen() const
|
||||||
*/
|
*/
|
||||||
size_t PasswordFile::size()
|
size_t PasswordFile::size()
|
||||||
{
|
{
|
||||||
if(!isOpen()) {
|
if (!isOpen()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
m_file.seekg(0, ios::end);
|
m_file.seekg(0, ios::end);
|
||||||
return m_file.tellg();
|
return m_file.tellg();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,16 @@
|
||||||
#include <c++utilities/io/binaryreader.h>
|
#include <c++utilities/io/binaryreader.h>
|
||||||
#include <c++utilities/io/binarywriter.h>
|
#include <c++utilities/io/binarywriter.h>
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace Io {
|
namespace Io {
|
||||||
|
|
||||||
class NodeEntry;
|
class NodeEntry;
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT PasswordFile
|
class PASSWORD_FILE_EXPORT PasswordFile {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit PasswordFile();
|
explicit PasswordFile();
|
||||||
explicit PasswordFile(const std::string &path, const std::string &password);
|
explicit PasswordFile(const std::string &path, const std::string &password);
|
||||||
|
@ -44,6 +43,7 @@ public:
|
||||||
bool isEncryptionUsed();
|
bool isEncryptionUsed();
|
||||||
bool isOpen() const;
|
bool isOpen() const;
|
||||||
size_t size();
|
size_t size();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
char m_password[32];
|
char m_password[32];
|
||||||
|
@ -54,7 +54,6 @@ private:
|
||||||
IoUtilities::BinaryReader m_freader;
|
IoUtilities::BinaryReader m_freader;
|
||||||
IoUtilities::BinaryWriter m_fwriter;
|
IoUtilities::BinaryWriter m_fwriter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PASSWORDFILE_H
|
#endif // PASSWORDFILE_H
|
||||||
|
|
|
@ -35,7 +35,5 @@ void clean()
|
||||||
// remove error strings
|
// remove error strings
|
||||||
ERR_free_strings();
|
ERR_free_strings();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,7 @@ namespace OpenSsl {
|
||||||
|
|
||||||
void PASSWORD_FILE_EXPORT init();
|
void PASSWORD_FILE_EXPORT init();
|
||||||
void PASSWORD_FILE_EXPORT clean();
|
void PASSWORD_FILE_EXPORT clean();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // OPENSSL_H
|
#endif // OPENSSL_H
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#include <c++utilities/conversion/binaryconversion.h>
|
#include <c++utilities/conversion/binaryconversion.h>
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -27,20 +27,22 @@ namespace Util {
|
||||||
* \brief Constructs a new random device.
|
* \brief Constructs a new random device.
|
||||||
*/
|
*/
|
||||||
OpenSslRandomDevice::OpenSslRandomDevice()
|
OpenSslRandomDevice::OpenSslRandomDevice()
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates a new random number.
|
* \brief Generates a new random number.
|
||||||
*/
|
*/
|
||||||
uint32 OpenSslRandomDevice::operator ()() const {
|
uint32 OpenSslRandomDevice::operator()() const
|
||||||
|
{
|
||||||
unsigned char buf[4];
|
unsigned char buf[4];
|
||||||
if(RAND_bytes(buf, sizeof(buf))) {
|
if (RAND_bytes(buf, sizeof(buf))) {
|
||||||
return ConversionUtilities::LE::toUInt32(reinterpret_cast<char *>(buf));
|
return ConversionUtilities::LE::toUInt32(reinterpret_cast<char *>(buf));
|
||||||
} else {
|
} else {
|
||||||
string msg;
|
string msg;
|
||||||
unsigned long errorCode = ERR_get_error();
|
unsigned long errorCode = ERR_get_error();
|
||||||
while(errorCode != 0) {
|
while (errorCode != 0) {
|
||||||
if(!msg.empty()) {
|
if (!msg.empty()) {
|
||||||
msg += '\n';
|
msg += '\n';
|
||||||
}
|
}
|
||||||
msg += ERR_error_string(errorCode, 0);
|
msg += ERR_error_string(errorCode, 0);
|
||||||
|
@ -57,5 +59,4 @@ bool OpenSslRandomDevice::status() const
|
||||||
{
|
{
|
||||||
return RAND_status();
|
return RAND_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
|
|
||||||
class PASSWORD_FILE_EXPORT OpenSslRandomDevice
|
class PASSWORD_FILE_EXPORT OpenSslRandomDevice {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
OpenSslRandomDevice();
|
OpenSslRandomDevice();
|
||||||
uint32 operator()() const;
|
uint32 operator()() const;
|
||||||
bool status() const;
|
bool status() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // OPENSSLRANDOMDEVICE_H
|
#endif // OPENSSLRANDOMDEVICE_H
|
||||||
|
|
Loading…
Reference in New Issue