Merge branch 0.9 (pre-work for version 0.9)
This commit is contained in:
commit
cfe2a48ebc
@ -1,5 +1,6 @@
|
||||
Version 0.9.0 (unreleased)
|
||||
---------------
|
||||
(warning) file systems created with earlier CryFS versions are incompatible with this release
|
||||
* Fully support file access times
|
||||
* (for developers) New repository layout. All subrepositories have been merged to one directory
|
||||
* (for developers) Using CMake instead of biicode as build system
|
||||
|
@ -15,11 +15,11 @@ using cpputils::Data;
|
||||
namespace cryfs {
|
||||
|
||||
CryConfig::CryConfig()
|
||||
: _rootBlob(""), _encKey(""), _cipher("") {
|
||||
: _rootBlob(""), _encKey(""), _cipher(""), _version("") {
|
||||
}
|
||||
|
||||
CryConfig::CryConfig(CryConfig &&rhs)
|
||||
: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)) {
|
||||
: _rootBlob(std::move(rhs._rootBlob)), _encKey(std::move(rhs._encKey)), _cipher(std::move(rhs._cipher)), _version(std::move(rhs._version)) {
|
||||
}
|
||||
|
||||
CryConfig CryConfig::load(const Data &data) {
|
||||
@ -32,6 +32,7 @@ CryConfig CryConfig::load(const Data &data) {
|
||||
cfg._rootBlob = pt.get("cryfs.rootblob", "");
|
||||
cfg._encKey = pt.get("cryfs.key", "");
|
||||
cfg._cipher = pt.get("cryfs.cipher", "");
|
||||
cfg._version = pt.get("cryfs.version", "0.8"); // CryFS 0.8 didn't specify this field, so if the field doesn't exist, it's 0.8.
|
||||
return cfg;
|
||||
}
|
||||
|
||||
@ -41,6 +42,7 @@ Data CryConfig::save() const {
|
||||
pt.put("cryfs.rootblob", _rootBlob);
|
||||
pt.put("cryfs.key", _encKey);
|
||||
pt.put("cryfs.cipher", _cipher);
|
||||
pt.put("cryfs.version", _version);
|
||||
|
||||
stringstream stream;
|
||||
write_json(stream, pt);
|
||||
@ -71,4 +73,12 @@ void CryConfig::SetCipher(const std::string &value) {
|
||||
_cipher = value;
|
||||
}
|
||||
|
||||
const std::string &CryConfig::Version() const {
|
||||
return _version;
|
||||
}
|
||||
|
||||
void CryConfig::SetVersion(const std::string &value) {
|
||||
_version = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ public:
|
||||
const std::string &Cipher() const;
|
||||
void SetCipher(const std::string &value);
|
||||
|
||||
const std::string &Version() const;
|
||||
void SetVersion(const std::string &value);
|
||||
|
||||
static CryConfig load(const cpputils::Data &data);
|
||||
cpputils::Data save() const;
|
||||
|
||||
@ -31,6 +34,7 @@ private:
|
||||
std::string _rootBlob;
|
||||
std::string _encKey;
|
||||
std::string _cipher;
|
||||
std::string _version;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CryConfig);
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "CryConfigCreator.h"
|
||||
#include "CryCipher.h"
|
||||
#include <gitversion/version.h>
|
||||
|
||||
using cpputils::Console;
|
||||
using cpputils::unique_ref;
|
||||
@ -21,6 +22,7 @@ namespace cryfs {
|
||||
config.SetCipher(_generateCipher(cipherFromCommandLine));
|
||||
config.SetEncryptionKey(_generateEncKey(config.Cipher()));
|
||||
config.SetRootBlob(_generateRootBlobKey());
|
||||
config.SetVersion(version::VERSION_STRING);
|
||||
return config;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cpp-utils/random/Random.h>
|
||||
#include <cpp-utils/logging/logging.h>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <gitversion/version.h>
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
using cpputils::unique_ref;
|
||||
@ -37,12 +39,24 @@ optional<CryConfigFile> CryConfigLoader::_loadConfig(const bf::path &filename) {
|
||||
return none;
|
||||
}
|
||||
std::cout << "done" << std::endl;
|
||||
if (_cipherFromCommandLine != none && config->config()->Cipher() != *_cipherFromCommandLine) {
|
||||
throw std::runtime_error("Filesystem uses "+config->config()->Cipher()+" cipher and not "+*_cipherFromCommandLine+" as specified.");
|
||||
}
|
||||
_checkVersion(*config->config());
|
||||
_checkCipher(*config->config());
|
||||
return std::move(*config);
|
||||
}
|
||||
|
||||
void CryConfigLoader::_checkVersion(const CryConfig &config) {
|
||||
const string allowedVersionPrefix = string() + version::VERSION_COMPONENTS[0] + "." + version::VERSION_COMPONENTS[1] + ".";
|
||||
if (!boost::starts_with(config.Version(), allowedVersionPrefix)) {
|
||||
throw std::runtime_error(string() + "This filesystem was created with CryFS " + config.Version() + " and is incompatible. Please create a new one with your version of CryFS and migrate your data.");
|
||||
}
|
||||
}
|
||||
|
||||
void CryConfigLoader::_checkCipher(const CryConfig &config) const {
|
||||
if (_cipherFromCommandLine != none && config.Cipher() != *_cipherFromCommandLine) {
|
||||
throw std::runtime_error(string() + "Filesystem uses " + config.Cipher() + " cipher and not " + *_cipherFromCommandLine + " as specified.");
|
||||
}
|
||||
}
|
||||
|
||||
optional<CryConfigFile> CryConfigLoader::loadOrCreate(const bf::path &filename) {
|
||||
if (bf::exists(filename)) {
|
||||
return _loadConfig(filename);
|
||||
|
@ -21,6 +21,8 @@ public:
|
||||
private:
|
||||
boost::optional<CryConfigFile> _loadConfig(const boost::filesystem::path &filename);
|
||||
CryConfigFile _createConfig(const boost::filesystem::path &filename);
|
||||
static void _checkVersion(const CryConfig &config);
|
||||
void _checkCipher(const CryConfig &config) const;
|
||||
|
||||
CryConfigCreator _creator;
|
||||
cpputils::SCryptSettings _scryptSettings;
|
||||
|
@ -1,87 +1,116 @@
|
||||
#include "DirEntry.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using blockstore::Key;
|
||||
|
||||
namespace cryfs {
|
||||
namespace fsblobstore {
|
||||
|
||||
void DirEntry::serialize(uint8_t *dest) const {
|
||||
ASSERT(
|
||||
((type == fspp::Dir::EntryType::FILE) && S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode)) ||
|
||||
((type == fspp::Dir::EntryType::DIR) && !S_ISREG(mode) && S_ISDIR(mode) && !S_ISLNK(mode)) ||
|
||||
((type == fspp::Dir::EntryType::SYMLINK) && !S_ISREG(mode) && !S_ISDIR(mode) && S_ISLNK(mode))
|
||||
, "Wrong mode bit set for this type: "+std::to_string(mode & S_IFREG)+", "+std::to_string(mode&S_IFDIR)+", "+std::to_string(mode&S_IFLNK)+", "+std::to_string(static_cast<uint8_t>(type))
|
||||
);
|
||||
unsigned int offset = 0;
|
||||
*(dest+offset) = static_cast<uint8_t>(type);
|
||||
offset += 1;
|
||||
|
||||
std::memcpy(dest+offset, name.c_str(), name.size()+1);
|
||||
offset += name.size() + 1;
|
||||
|
||||
key.ToBinary(dest+offset);
|
||||
offset += key.BINARY_LENGTH;
|
||||
|
||||
*reinterpret_cast<uid_t*>(dest+offset) = uid;
|
||||
offset += sizeof(uid_t);
|
||||
|
||||
*reinterpret_cast<gid_t*>(dest+offset) = gid;
|
||||
offset += sizeof(gid_t);
|
||||
|
||||
*reinterpret_cast<mode_t*>(dest+offset) = mode;
|
||||
offset += sizeof(mode_t);
|
||||
|
||||
//TODO Persist times, see comment in deserializeAndAddToVector()
|
||||
//static_assert(sizeof(timespec) == 16, "Ensure platform independence of the serialization");
|
||||
//*reinterpret_cast<timespec*>(dest+offset) = lastAccessTime;
|
||||
//offset += sizeof(timespec);
|
||||
//*reinterpret_cast<timespec*>(dest+offset) = lastModificationTime;
|
||||
//offset += sizeof(timespec);
|
||||
//*reinterpret_cast<timespec*>(dest+offset) = lastMetadataChangeTime;
|
||||
//offset += sizeof(timespec);
|
||||
|
||||
offset += _serializeUint8(dest + offset, static_cast<uint8_t>(type));
|
||||
offset += _serializeUint32(dest + offset, mode);
|
||||
offset += _serializeUint32(dest + offset, uid);
|
||||
offset += _serializeUint32(dest + offset, gid);
|
||||
offset += _serializeTimeValue(dest + offset, lastAccessTime);
|
||||
offset += _serializeTimeValue(dest + offset, lastModificationTime);
|
||||
offset += _serializeTimeValue(dest + offset, lastMetadataChangeTime);
|
||||
offset += _serializeString(dest + offset, name);
|
||||
offset += _serializeKey(dest + offset, key);
|
||||
ASSERT(offset == serializedSize(), "Didn't write correct number of elements");
|
||||
}
|
||||
|
||||
size_t DirEntry::serializedSize() const {
|
||||
//TODO Persist times, see comment in deserializeAndAddToVector()
|
||||
//return 1 + (name.size() + 1) + key.BINARY_LENGTH + sizeof(uid_t) + sizeof(gid_t) + sizeof(mode_t) + 3*sizeof(timespec);
|
||||
return 1 + (name.size() + 1) + key.BINARY_LENGTH + sizeof(uid_t) + sizeof(gid_t) + sizeof(mode_t);
|
||||
}
|
||||
|
||||
const char *DirEntry::deserializeAndAddToVector(const char *pos, vector<DirEntry> *result) {
|
||||
// Read type magic number (whether it is a dir or a file)
|
||||
fspp::Dir::EntryType type =
|
||||
static_cast<fspp::Dir::EntryType>(*reinterpret_cast<const unsigned char*>(pos));
|
||||
pos += 1;
|
||||
|
||||
size_t namelength = strlen(pos);
|
||||
std::string name(pos, namelength);
|
||||
pos += namelength + 1;
|
||||
|
||||
Key key = Key::FromBinary(pos);
|
||||
pos += Key::BINARY_LENGTH;
|
||||
|
||||
uid_t uid = *(uid_t*)pos;
|
||||
pos += sizeof(uid_t);
|
||||
|
||||
gid_t gid = *(gid_t*)pos;
|
||||
pos += sizeof(gid_t);
|
||||
|
||||
mode_t mode = *(mode_t*)pos;
|
||||
pos += sizeof(mode_t);
|
||||
|
||||
//TODO Persist times. This breaks compatibility though - so change cryfs::InnerConfig::HEADER
|
||||
// This is already implemented, but I commented it out for now, because it would break compatibility.
|
||||
//timespec lastAccessTime = *(timespec*)pos;
|
||||
//pos += sizeof(timespec);
|
||||
//timespec lastModificationTime = *(timespec*)pos;
|
||||
//pos += sizeof(timespec);
|
||||
//timespec lastMetadataChangeTime = *(timespec*)pos;
|
||||
//pos += sizeof(timespec);
|
||||
timespec lastAccessTime;
|
||||
clock_gettime(CLOCK_REALTIME, &lastAccessTime);
|
||||
timespec lastModificationTime = lastAccessTime;
|
||||
timespec lastMetadataChangeTime = lastAccessTime;
|
||||
fspp::Dir::EntryType type = static_cast<fspp::Dir::EntryType>(_deserializeUint8(&pos));
|
||||
mode_t mode = _deserializeUint32(&pos);
|
||||
uid_t uid = _deserializeUint32(&pos);
|
||||
gid_t gid = _deserializeUint32(&pos);
|
||||
timespec lastAccessTime = _deserializeTimeValue(&pos);
|
||||
timespec lastModificationTime = _deserializeTimeValue(&pos);
|
||||
timespec lastMetadataChangeTime = _deserializeTimeValue(&pos);
|
||||
string name = _deserializeString(&pos);
|
||||
Key key = _deserializeKey(&pos);
|
||||
|
||||
result->emplace_back(type, name, key, mode, uid, gid, lastAccessTime, lastModificationTime, lastMetadataChangeTime);
|
||||
return pos;
|
||||
}
|
||||
|
||||
unsigned int DirEntry::_serializeTimeValue(uint8_t *dest, timespec value) {
|
||||
unsigned int offset = 0;
|
||||
*reinterpret_cast<uint64_t*>(dest+offset) = value.tv_sec;
|
||||
offset += sizeof(uint64_t);
|
||||
*reinterpret_cast<uint32_t*>(dest+offset) = value.tv_nsec;
|
||||
offset += sizeof(uint32_t);
|
||||
ASSERT(offset == _serializedTimeValueSize(), "serialized to wrong size");
|
||||
return offset;
|
||||
}
|
||||
|
||||
size_t DirEntry::_serializedTimeValueSize() {
|
||||
return sizeof(uint64_t) + sizeof(uint32_t);
|
||||
}
|
||||
|
||||
timespec DirEntry::_deserializeTimeValue(const char **pos) {
|
||||
timespec value;
|
||||
value.tv_sec = *(uint64_t*)(*pos);
|
||||
*pos += sizeof(uint64_t);
|
||||
value.tv_nsec = *(uint32_t*)(*pos);
|
||||
*pos += sizeof(uint32_t);
|
||||
return value;
|
||||
}
|
||||
|
||||
unsigned int DirEntry::_serializeUint8(uint8_t *dest, uint8_t value) {
|
||||
*reinterpret_cast<uint8_t*>(dest) = value;
|
||||
return sizeof(uint8_t);
|
||||
}
|
||||
|
||||
uint8_t DirEntry::_deserializeUint8(const char **pos) {
|
||||
uint8_t value = *(uint8_t*)(*pos);
|
||||
*pos += sizeof(uint8_t);
|
||||
return value;
|
||||
}
|
||||
|
||||
unsigned int DirEntry::_serializeUint32(uint8_t *dest, uint32_t value) {
|
||||
*reinterpret_cast<uint32_t*>(dest) = value;
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
uint32_t DirEntry::_deserializeUint32(const char **pos) {
|
||||
uint32_t value = *(uint32_t*)(*pos);
|
||||
*pos += sizeof(uint32_t);
|
||||
return value;
|
||||
}
|
||||
|
||||
unsigned int DirEntry::_serializeString(uint8_t *dest, const string &value) {
|
||||
std::memcpy(dest, value.c_str(), value.size()+1);
|
||||
return value.size() + 1;
|
||||
}
|
||||
|
||||
string DirEntry::_deserializeString(const char **pos) {
|
||||
size_t length = strlen(*pos);
|
||||
string value(*pos, length);
|
||||
*pos += length + 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
unsigned int DirEntry::_serializeKey(uint8_t *dest, const Key &key) {
|
||||
key.ToBinary(dest);
|
||||
return key.BINARY_LENGTH;
|
||||
}
|
||||
|
||||
Key DirEntry::_deserializeKey(const char **pos) {
|
||||
Key key = Key::FromBinary(*pos);
|
||||
*pos += Key::BINARY_LENGTH;
|
||||
return key;
|
||||
}
|
||||
|
||||
size_t DirEntry::serializedSize() const {
|
||||
return 1 + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + 3*_serializedTimeValueSize() + (name.size() + 1) + key.BINARY_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,17 @@ namespace cryfs {
|
||||
void serialize(uint8_t* dest) const;
|
||||
size_t serializedSize() const;
|
||||
static const char *deserializeAndAddToVector(const char *pos, std::vector<DirEntry> *result);
|
||||
static size_t _serializedTimeValueSize();
|
||||
static unsigned int _serializeTimeValue(uint8_t *dest, timespec value);
|
||||
static unsigned int _serializeUint8(uint8_t *dest, uint8_t value);
|
||||
static unsigned int _serializeUint32(uint8_t *dest, uint32_t value);
|
||||
static unsigned int _serializeString(uint8_t *dest, const std::string &value);
|
||||
static unsigned int _serializeKey(uint8_t *dest, const blockstore::Key &value);
|
||||
static timespec _deserializeTimeValue(const char **pos);
|
||||
static uint8_t _deserializeUint8(const char **pos);
|
||||
static uint32_t _deserializeUint32(const char **pos);
|
||||
static std::string _deserializeString(const char **pos);
|
||||
static blockstore::Key _deserializeKey(const char **pos);
|
||||
|
||||
fspp::Dir::EntryType type;
|
||||
std::string name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user