Compare commits
15 Commits
Author | SHA1 | Date |
---|---|---|
Matéo Duparc | 35a2198ac9 | |
Matéo Duparc | 267fb40fe7 | |
Matéo Duparc | f03d39433c | |
Matéo Duparc | 9c19680b55 | |
Matéo Duparc | fb593c468c | |
Matéo Duparc | ac2b8a615b | |
Matéo Duparc | f89ac70d59 | |
Matéo Duparc | 6cd6d9ef5d | |
Matéo Duparc | 412df2e7be | |
Matéo Duparc | e9f000353b | |
Matéo Duparc | 03fffc44a5 | |
Matéo Duparc | 56c7d96bbf | |
Matéo Duparc | e6d735dbab | |
Matéo Duparc | 3866607d68 | |
Matéo Duparc | 3df8023b21 |
|
@ -42,8 +42,5 @@ if(MSVC)
|
||||||
add_definitions(/bigobj)
|
add_definitions(/bigobj)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Hardcoded version. Don't forget to change this when merging upstream!
|
|
||||||
set(GIT_VERSION "0.11.4-libcryfs")
|
|
||||||
|
|
||||||
add_subdirectory(vendor EXCLUDE_FROM_ALL)
|
add_subdirectory(vendor EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
Version 0.11.4
|
Version 0.12.0 (unreleased)
|
||||||
---------------
|
---------------
|
||||||
* Fixed build issue with GCC 13 (see https://github.com/cryfs/cryfs/pull/448 )
|
* Updated to DokanY 1.3.0.1000
|
||||||
* Fixed build issue with Python 3.12 (see https://github.com/cryfs/cryfs/issues/459 )
|
|
||||||
|
|
||||||
Version 0.11.3
|
|
||||||
---------------
|
|
||||||
* Fixed build issue on systems with libfmt 9.0 (see https://github.com/cryfs/cryfs/issues/432 )
|
|
||||||
* Fixed build issue on Apple Silicon Macs (see https://github.com/cryfs/homebrew-tap/issues/10 )
|
|
||||||
* Fixed build issue on systems that only have `python3` but no `python` executable (see https://github.com/cryfs/homebrew-tap/issues/12 )
|
|
||||||
|
|
||||||
Version 0.11.2
|
Version 0.11.2
|
||||||
---------------
|
---------------
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
libcryfs is a re-design of the original [CryFS](https://github.com/cryfs/cryfs) code to work as a library. Volumes are not mounted with [FUSE](https://www.kernel.org/doc/html/latest/filesystems/fuse.html) but rather opened in memory and accessed through API calls. What's the purpose ?
|
libcryfs is a re-desing of the original [CryFS](https://github.com/cryfs/cryfs) code to work as a library. Volumes are not mounted with [FUSE](https://www.kernel.org/doc/html/latest/filesystems/fuse.html) but rather opened in memory and accessed through API calls. What the purpose ?
|
||||||
- Allow the use of CryFS on platforms where FUSE is not available (such as Android)
|
- Allow the use of CryFS on platforms where FUSE is not available (such as Android)
|
||||||
- Reduce attack surface by restricting volumes access to only one process rather than one user
|
- Reduce attack surface by restricting volumes access to only one process rather than one user
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ Here is what has been modified from the original project:
|
||||||
- sh scripts, `cpack`, `doc`, `test` and `vendor/googletest` deleted
|
- sh scripts, `cpack`, `doc`, `test` and `vendor/googletest` deleted
|
||||||
- Main program `cryfs-cli` removed
|
- Main program `cryfs-cli` removed
|
||||||
- boost build configured with [Boost-for-Android](https://github.com/moritz-wundke/Boost-for-Android)
|
- boost build configured with [Boost-for-Android](https://github.com/moritz-wundke/Boost-for-Android)
|
||||||
- Automatic version detection removed
|
|
||||||
- Interactive mode removed (including any writes to stdout)
|
- Interactive mode removed (including any writes to stdout)
|
||||||
- Logging output redirected to logcat
|
- Logging output redirected to logcat
|
||||||
- JNI API created in `src/jni`
|
- JNI API created in `src/jni`
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#ifndef CPPUTILS_SIZEDDATA_H
|
|
||||||
#define CPPUTILS_SIZEDDATA_H
|
|
||||||
|
|
||||||
struct SizedData {
|
|
||||||
unsigned char* data;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <cpp-utils/macros.h>
|
#include <cpp-utils/macros.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace cpputils {
|
namespace cpputils {
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <cpp-utils/io/DontEchoStdinToStdoutRAII.h>
|
#include <cpp-utils/io/DontEchoStdinToStdoutRAII.h>
|
||||||
#include <cryfs/impl/filesystem/CryDevice.h>
|
#include <cryfs/impl/filesystem/CryDevice.h>
|
||||||
#include <cryfs/impl/config/CryConfigLoader.h>
|
#include <cryfs/impl/config/CryConfigLoader.h>
|
||||||
#include <cryfs/impl/config/CryDirectKeyProvider.h>
|
|
||||||
#include <cryfs/impl/config/CryPresetPasswordBasedKeyProvider.h>
|
#include <cryfs/impl/config/CryPresetPasswordBasedKeyProvider.h>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
@ -90,9 +89,9 @@ namespace cryfs_cli {
|
||||||
basedirMetadata.save();
|
basedirMetadata.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
CryConfigLoader::ConfigLoadResult Cli::_loadOrCreateConfig(const ProgramOptions &options, const LocalStateDir& localStateDir, Credentials credentials) {
|
CryConfigLoader::ConfigLoadResult Cli::_loadOrCreateConfig(const ProgramOptions &options, const LocalStateDir& localStateDir, unique_ptr<string> password) {
|
||||||
auto configFile = _determineConfigFile(options);
|
auto configFile = _determineConfigFile(options);
|
||||||
auto config = _loadOrCreateConfigFile(std::move(configFile), localStateDir, credentials, options.cipher(), options.blocksizeBytes(), options.allowFilesystemUpgrade(), options.missingBlockIsIntegrityViolation(), options.allowReplacedFilesystem());
|
auto config = _loadOrCreateConfigFile(std::move(configFile), localStateDir, std::move(password), options.cipher(), options.blocksizeBytes(), options.allowFilesystemUpgrade(), options.missingBlockIsIntegrityViolation(), options.allowReplacedFilesystem());
|
||||||
if (config.is_left()) {
|
if (config.is_left()) {
|
||||||
switch(config.left()) {
|
switch(config.left()) {
|
||||||
case CryConfigFile::LoadError::DecryptionFailed:
|
case CryConfigFile::LoadError::DecryptionFailed:
|
||||||
|
@ -105,30 +104,24 @@ namespace cryfs_cli {
|
||||||
return std::move(config.right());
|
return std::move(config.right());
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ref<CryKeyProvider> Cli::_createKeyProvider(Credentials credentials) {
|
either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> Cli::_loadOrCreateConfigFile(bf::path configFilePath, LocalStateDir localStateDir, unique_ptr<string> password, const optional<string> &cipher, const optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem) {
|
||||||
if (credentials.password == none) {
|
// TODO Instead of passing in _askPasswordXXX functions to KeyProvider, only pass in console and move logic to the key provider,
|
||||||
return make_unique_ref<CryDirectKeyProvider>(credentials.givenHash);
|
// for example by having a separate CryPasswordBasedKeyProvider / CryNoninteractivePasswordBasedKeyProvider.
|
||||||
} else {
|
auto keyProvider = make_unique_ref<CryPresetPasswordBasedKeyProvider>(
|
||||||
return make_unique_ref<CryPresetPasswordBasedKeyProvider>(
|
*password.get(),
|
||||||
*credentials.password,
|
make_unique_ref<SCrypt>(_scryptSettings)
|
||||||
make_unique_ref<SCrypt>(_scryptSettings),
|
);
|
||||||
credentials.returnedHash
|
return CryConfigLoader(_keyGenerator, std::move(keyProvider), std::move(localStateDir), cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath), allowFilesystemUpgrade, allowReplacedFilesystem);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> Cli::_loadOrCreateConfigFile(bf::path configFilePath, LocalStateDir localStateDir, Credentials credentials, const optional<string> &cipher, const optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem) {
|
fspp::fuse::Fuse* Cli::initFilesystem(const ProgramOptions &options, unique_ptr<string> password) {
|
||||||
return CryConfigLoader(_keyGenerator, _createKeyProvider(credentials), std::move(localStateDir), cipher, blocksizeBytes, missingBlockIsIntegrityViolation).loadOrCreate(std::move(configFilePath), allowFilesystemUpgrade, allowReplacedFilesystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
fspp::fuse::Fuse* Cli::initFilesystem(const ProgramOptions &options, Credentials credentials) {
|
|
||||||
cpputils::showBacktraceOnCrash();
|
cpputils::showBacktraceOnCrash();
|
||||||
cpputils::set_thread_name("cryfs");
|
cpputils::set_thread_name("cryfs");
|
||||||
try {
|
try {
|
||||||
_sanityChecks(options);
|
_sanityChecks(options);
|
||||||
LocalStateDir localStateDir(options.localStateDir());
|
LocalStateDir localStateDir(options.localStateDir());
|
||||||
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
|
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
|
||||||
auto config = _loadOrCreateConfig(options, localStateDir, credentials);
|
auto config = _loadOrCreateConfig(options, localStateDir, std::move(password));
|
||||||
fspp::fuse::Fuse* fuse = nullptr;
|
fspp::fuse::Fuse* fuse = nullptr;
|
||||||
|
|
||||||
auto onIntegrityViolation = [&fuse] () {
|
auto onIntegrityViolation = [&fuse] () {
|
||||||
|
@ -152,12 +145,14 @@ namespace cryfs_cli {
|
||||||
return make_shared<fspp::FilesystemImpl>(std::move(*_device));
|
return make_shared<fspp::FilesystemImpl>(std::move(*_device));
|
||||||
};
|
};
|
||||||
|
|
||||||
fuse = new fspp::fuse::Fuse(initFilesystem);
|
fuse = new fspp::fuse::Fuse(initFilesystem, "cryfs", "cryfs@" + options.baseDir().string());
|
||||||
|
|
||||||
fuse->init();
|
fuse->init();
|
||||||
return fuse;
|
return fuse;
|
||||||
} catch (const CryfsException &e) {
|
} catch (const CryfsException &e) {
|
||||||
throw; // CryfsException is only thrown if setup goes wrong. Throw it through so that we get the correct process exit code.
|
if (e.what() != string()) {
|
||||||
|
LOG(ERR, "Error {}: {}", static_cast<int>(e.errorCode()), e.what());
|
||||||
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
LOG(ERR, "Crashed: {}", e.what());
|
LOG(ERR, "Crashed: {}", e.what());
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
|
@ -5,13 +5,11 @@
|
||||||
#include <fspp/fuse/Fuse.h>
|
#include <fspp/fuse/Fuse.h>
|
||||||
#include "program_options/ProgramOptions.h"
|
#include "program_options/ProgramOptions.h"
|
||||||
#include <cryfs/impl/config/CryConfigFile.h>
|
#include <cryfs/impl/config/CryConfigFile.h>
|
||||||
#include <cryfs/impl/config/CryKeyProvider.h>
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <cpp-utils/tempfile/TempFile.h>
|
#include <cpp-utils/tempfile/TempFile.h>
|
||||||
#include <cpp-utils/io/Console.h>
|
#include <cpp-utils/io/Console.h>
|
||||||
#include <cpp-utils/random/RandomGenerator.h>
|
#include <cpp-utils/random/RandomGenerator.h>
|
||||||
#include <cpp-utils/network/HttpClient.h>
|
#include <cpp-utils/network/HttpClient.h>
|
||||||
#include <cpp-utils/SizedData.h>
|
|
||||||
#include <cryfs/impl/filesystem/CryDevice.h>
|
#include <cryfs/impl/filesystem/CryDevice.h>
|
||||||
#include "CallAfterTimeout.h"
|
#include "CallAfterTimeout.h"
|
||||||
#include <cryfs/impl/config/CryConfigLoader.h>
|
#include <cryfs/impl/config/CryConfigLoader.h>
|
||||||
|
@ -20,20 +18,16 @@
|
||||||
namespace cryfs_cli {
|
namespace cryfs_cli {
|
||||||
class Cli final {
|
class Cli final {
|
||||||
public:
|
public:
|
||||||
struct Credentials {
|
|
||||||
boost::optional<string> password;
|
|
||||||
SizedData givenHash;
|
|
||||||
SizedData* returnedHash;
|
|
||||||
};
|
|
||||||
Cli(cpputils::RandomGenerator &keyGenerator, const cpputils::SCryptSettings& scryptSettings);
|
Cli(cpputils::RandomGenerator &keyGenerator, const cpputils::SCryptSettings& scryptSettings);
|
||||||
fspp::fuse::Fuse* initFilesystem(const program_options::ProgramOptions &options, Credentials credentials);
|
fspp::fuse::Fuse* initFilesystem(const program_options::ProgramOptions &options, std::unique_ptr<string> password);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cryfs::CryConfigLoader::ConfigLoadResult _loadOrCreateConfig(const program_options::ProgramOptions &options, const cryfs::LocalStateDir& localStateDir, Credentials credentials);
|
void _checkForUpdates(cpputils::unique_ref<cpputils::HttpClient> httpClient);
|
||||||
|
cryfs::CryConfigLoader::ConfigLoadResult _loadOrCreateConfig(const program_options::ProgramOptions &options, const cryfs::LocalStateDir& localStateDir, std::unique_ptr<string> password);
|
||||||
void _checkConfigIntegrity(const boost::filesystem::path& basedir, const cryfs::LocalStateDir& localStateDir, const cryfs::CryConfigFile& config, bool allowReplacedFilesystem);
|
void _checkConfigIntegrity(const boost::filesystem::path& basedir, const cryfs::LocalStateDir& localStateDir, const cryfs::CryConfigFile& config, bool allowReplacedFilesystem);
|
||||||
cpputils::unique_ref<cryfs::CryKeyProvider> _createKeyProvider(Credentials credentials);
|
cpputils::either<cryfs::CryConfigFile::LoadError, cryfs::CryConfigLoader::ConfigLoadResult> _loadOrCreateConfigFile(boost::filesystem::path configFilePath, cryfs::LocalStateDir localStateDir, std::unique_ptr<string> password, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const boost::optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem);
|
||||||
cpputils::either<cryfs::CryConfigFile::LoadError, cryfs::CryConfigLoader::ConfigLoadResult> _loadOrCreateConfigFile(boost::filesystem::path configFilePath, cryfs::LocalStateDir localStateDir, Credentials credentials, const boost::optional<std::string> &cipher, const boost::optional<uint32_t> &blocksizeBytes, bool allowFilesystemUpgrade, const boost::optional<bool> &missingBlockIsIntegrityViolation, bool allowReplacedFilesystem);
|
|
||||||
boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options);
|
boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options);
|
||||||
|
void _initLogfile();
|
||||||
void _sanityChecks(const program_options::ProgramOptions &options);
|
void _sanityChecks(const program_options::ProgramOptions &options);
|
||||||
void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name, bool createMissingDir, cryfs::ErrorCode errorCode);
|
void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name, bool createMissingDir, cryfs::ErrorCode errorCode);
|
||||||
void _sanityCheckFilesystem(cryfs::CryDevice *device);
|
void _sanityCheckFilesystem(cryfs::CryDevice *device);
|
||||||
|
|
|
@ -19,7 +19,6 @@ set(LIB_SOURCES
|
||||||
impl/config/CryKeyProvider.cpp
|
impl/config/CryKeyProvider.cpp
|
||||||
impl/config/CryPasswordBasedKeyProvider.cpp
|
impl/config/CryPasswordBasedKeyProvider.cpp
|
||||||
impl/config/CryPresetPasswordBasedKeyProvider.cpp
|
impl/config/CryPresetPasswordBasedKeyProvider.cpp
|
||||||
impl/config/CryDirectKeyProvider.cpp
|
|
||||||
impl/filesystem/CryOpenFile.cpp
|
impl/filesystem/CryOpenFile.cpp
|
||||||
impl/filesystem/fsblobstore/utils/DirEntry.cpp
|
impl/filesystem/fsblobstore/utils/DirEntry.cpp
|
||||||
impl/filesystem/fsblobstore/utils/DirEntryList.cpp
|
impl/filesystem/fsblobstore/utils/DirEntryList.cpp
|
||||||
|
|
|
@ -93,6 +93,8 @@ void CryConfigLoader::_checkMissingBlocksAreIntegrityViolations(CryConfigFile *c
|
||||||
auto exclusiveClientId = configFile->config()->ExclusiveClientId();
|
auto exclusiveClientId = configFile->config()->ExclusiveClientId();
|
||||||
if (exclusiveClientId != none && *exclusiveClientId != myClientId) {
|
if (exclusiveClientId != none && *exclusiveClientId != myClientId) {
|
||||||
throw CryfsException("File system is in single-client mode and can only be used from the client that created it.", ErrorCode::SingleClientFileSystem);
|
throw CryfsException("File system is in single-client mode and can only be used from the client that created it.", ErrorCode::SingleClientFileSystem);
|
||||||
|
configFile->config()->SetExclusiveClientId(none);
|
||||||
|
configFile->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,15 +110,6 @@ either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> CryConfigLoa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<CryConfigFile::LoadError> CryConfigLoader::changeEncryptionKey(bf::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, unique_ref<CryKeyProvider> newKeyProvider) {
|
|
||||||
auto config = _loadConfig(filename, allowFilesystemUpgrade, allowReplacedFilesystem, CryConfigFile::Access::ReadWrite);
|
|
||||||
if (config.is_left()) {
|
|
||||||
return config.left();
|
|
||||||
}
|
|
||||||
CryConfigFile(filename, *config.right().configFile->config(), CryConfigEncryptorFactory::deriveNewKey(newKeyProvider.get()), CryConfigFile::Access::ReadWrite).save();
|
|
||||||
return none;
|
|
||||||
}
|
|
||||||
|
|
||||||
CryConfigLoader::ConfigLoadResult CryConfigLoader::_createConfig(bf::path filename, bool allowReplacedFilesystem) {
|
CryConfigLoader::ConfigLoadResult CryConfigLoader::_createConfig(bf::path filename, bool allowReplacedFilesystem) {
|
||||||
auto config = _creator.create(_cipherFromCommandLine, _blocksizeBytesFromCommandLine, _missingBlockIsIntegrityViolationFromCommandLine, allowReplacedFilesystem);
|
auto config = _creator.create(_cipherFromCommandLine, _blocksizeBytesFromCommandLine, _missingBlockIsIntegrityViolationFromCommandLine, allowReplacedFilesystem);
|
||||||
auto result = CryConfigFile::create(std::move(filename), config.config, _keyProvider.get());
|
auto result = CryConfigFile::create(std::move(filename), config.config, _keyProvider.get());
|
||||||
|
|
|
@ -26,7 +26,6 @@ public:
|
||||||
|
|
||||||
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> loadOrCreate(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem);
|
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> loadOrCreate(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem);
|
||||||
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> load(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, CryConfigFile::Access access);
|
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> load(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, CryConfigFile::Access access);
|
||||||
boost::optional<CryConfigFile::LoadError> changeEncryptionKey(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, cpputils::unique_ref<CryKeyProvider> newKeyProvider);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> _loadConfig(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, CryConfigFile::Access access);
|
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> _loadConfig(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, CryConfigFile::Access access);
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#include "CryDirectKeyProvider.h"
|
|
||||||
|
|
||||||
namespace cryfs {
|
|
||||||
|
|
||||||
CryDirectKeyProvider::CryDirectKeyProvider(SizedData encryptionKey) : _encryptionKey(encryptionKey) {}
|
|
||||||
|
|
||||||
cpputils::EncryptionKey CryDirectKeyProvider::requestKeyForExistingFilesystem(size_t keySize, const cpputils::Data& kdfParameters) {
|
|
||||||
ASSERT(_encryptionKey.size == keySize, "CryDirectKeyProvider: Invalid key size requested");
|
|
||||||
cpputils::EncryptionKey encryptionKey = cpputils::EncryptionKey::Null(_encryptionKey.size);
|
|
||||||
memcpy(encryptionKey.data(), _encryptionKey.data, _encryptionKey.size);
|
|
||||||
return encryptionKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
CryKeyProvider::KeyResult CryDirectKeyProvider::requestKeyForNewFilesystem(size_t keySize) {
|
|
||||||
throw std::logic_error("CryDirectKeyProvider can't be used for new filesystems");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#ifndef CRYFS_CRYDIRECTKEYPROVIDER_H
|
|
||||||
#define CRYFS_CRYDIRECTKEYPROVIDER_H
|
|
||||||
|
|
||||||
#include "CryKeyProvider.h"
|
|
||||||
#include <cpp-utils/SizedData.h>
|
|
||||||
|
|
||||||
namespace cryfs {
|
|
||||||
|
|
||||||
class CryDirectKeyProvider final : public CryKeyProvider {
|
|
||||||
public:
|
|
||||||
explicit CryDirectKeyProvider(SizedData encryptionKey);
|
|
||||||
|
|
||||||
cpputils::EncryptionKey requestKeyForExistingFilesystem(size_t keySize, const cpputils::Data& kdfParameters) override;
|
|
||||||
KeyResult requestKeyForNewFilesystem(size_t keySize) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
SizedData _encryptionKey;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CryDirectKeyProvider);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -8,26 +8,15 @@ using cpputils::Data;
|
||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
CryPresetPasswordBasedKeyProvider::CryPresetPasswordBasedKeyProvider(std::string password, unique_ref<PasswordBasedKDF> kdf, SizedData* returnedHash)
|
CryPresetPasswordBasedKeyProvider::CryPresetPasswordBasedKeyProvider(std::string password, unique_ref<PasswordBasedKDF> kdf)
|
||||||
: _password(std::move(password)), _kdf(std::move(kdf)), _returnedHash(returnedHash) {}
|
: _password(std::move(password)), _kdf(std::move(kdf)) {}
|
||||||
|
|
||||||
void CryPresetPasswordBasedKeyProvider::saveEncryptionKey(EncryptionKey encryptionKey) {
|
|
||||||
if (_returnedHash != nullptr) {
|
|
||||||
_returnedHash->size = encryptionKey.binaryLength();
|
|
||||||
_returnedHash->data = new unsigned char[_returnedHash->size];
|
|
||||||
memcpy(_returnedHash->data, encryptionKey.data(), _returnedHash->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EncryptionKey CryPresetPasswordBasedKeyProvider::requestKeyForExistingFilesystem(size_t keySize, const Data& kdfParameters) {
|
EncryptionKey CryPresetPasswordBasedKeyProvider::requestKeyForExistingFilesystem(size_t keySize, const Data& kdfParameters) {
|
||||||
EncryptionKey encryptionKey = _kdf->deriveExistingKey(keySize, _password, kdfParameters);
|
return _kdf->deriveExistingKey(keySize, _password, kdfParameters);
|
||||||
saveEncryptionKey(encryptionKey);
|
|
||||||
return encryptionKey;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CryPresetPasswordBasedKeyProvider::KeyResult CryPresetPasswordBasedKeyProvider::requestKeyForNewFilesystem(size_t keySize) {
|
CryPresetPasswordBasedKeyProvider::KeyResult CryPresetPasswordBasedKeyProvider::requestKeyForNewFilesystem(size_t keySize) {
|
||||||
auto keyResult = _kdf->deriveNewKey(keySize, _password);
|
auto keyResult = _kdf->deriveNewKey(keySize, _password);
|
||||||
saveEncryptionKey(keyResult.key);
|
|
||||||
return {std::move(keyResult.key), std::move(keyResult.kdfParameters)};
|
return {std::move(keyResult.key), std::move(keyResult.kdfParameters)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,27 +5,19 @@
|
||||||
#include "CryKeyProvider.h"
|
#include "CryKeyProvider.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cpp-utils/crypto/kdf/PasswordBasedKDF.h>
|
#include <cpp-utils/crypto/kdf/PasswordBasedKDF.h>
|
||||||
#include <cpp-utils/SizedData.h>
|
|
||||||
|
|
||||||
namespace cryfs {
|
namespace cryfs {
|
||||||
|
|
||||||
class CryPresetPasswordBasedKeyProvider final : public CryKeyProvider {
|
class CryPresetPasswordBasedKeyProvider final : public CryKeyProvider {
|
||||||
public:
|
public:
|
||||||
explicit CryPresetPasswordBasedKeyProvider(
|
explicit CryPresetPasswordBasedKeyProvider(std::string password, cpputils::unique_ref<cpputils::PasswordBasedKDF> kdf);
|
||||||
std::string password,
|
|
||||||
cpputils::unique_ref<cpputils::PasswordBasedKDF> kdf,
|
|
||||||
SizedData* returnedHash
|
|
||||||
);
|
|
||||||
|
|
||||||
cpputils::EncryptionKey requestKeyForExistingFilesystem(size_t keySize, const cpputils::Data& kdfParameters) override;
|
cpputils::EncryptionKey requestKeyForExistingFilesystem(size_t keySize, const cpputils::Data& kdfParameters) override;
|
||||||
KeyResult requestKeyForNewFilesystem(size_t keySize) override;
|
KeyResult requestKeyForNewFilesystem(size_t keySize) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveEncryptionKey(cpputils::EncryptionKey encryptionKey);
|
|
||||||
|
|
||||||
std::string _password;
|
std::string _password;
|
||||||
cpputils::unique_ref<cpputils::PasswordBasedKDF> _kdf;
|
cpputils::unique_ref<cpputils::PasswordBasedKDF> _kdf;
|
||||||
SizedData* _returnedHash;
|
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(CryPresetPasswordBasedKeyProvider);
|
DISALLOW_COPY_AND_ASSIGN(CryPresetPasswordBasedKeyProvider);
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,8 +58,16 @@ public:
|
||||||
// Remove the following line, if you don't want to output each fuse operation on the console
|
// Remove the following line, if you don't want to output each fuse operation on the console
|
||||||
//#define FSPP_LOG 1
|
//#define FSPP_LOG 1
|
||||||
|
|
||||||
Fuse::Fuse(std::function<shared_ptr<Filesystem> ()> init)
|
Fuse::~Fuse() {
|
||||||
:_init(std::move(init)), _fs(make_shared<InvalidFilesystem>()), _running(false) {
|
for(char *arg : _argv) {
|
||||||
|
delete[] arg;
|
||||||
|
arg = nullptr;
|
||||||
|
}
|
||||||
|
_argv.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Fuse::Fuse(std::function<shared_ptr<Filesystem> ()> init, std::string fstype, boost::optional<std::string> fsname)
|
||||||
|
:_init(std::move(init)), _fs(make_shared<InvalidFilesystem>()), _running(false), _fstype(std::move(fstype)), _fsname(std::move(fsname)) {
|
||||||
ASSERT(static_cast<bool>(_init), "Invalid init given");
|
ASSERT(static_cast<bool>(_init), "Invalid init given");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,14 +198,14 @@ int Fuse::readlink(const bf::path &path, char *buf, size_t size) {
|
||||||
int Fuse::mkdir(const bf::path &path, ::mode_t mode) {
|
int Fuse::mkdir(const bf::path &path, ::mode_t mode) {
|
||||||
ThreadNameForDebugging _threadName("mkdir");
|
ThreadNameForDebugging _threadName("mkdir");
|
||||||
#ifdef FSPP_LOG
|
#ifdef FSPP_LOG
|
||||||
LOG(DEBUG, "mkdir({}, {})", path.string(), mode);
|
LOG(DEBUG, "mkdir({}, {})", path, mode);
|
||||||
#endif
|
#endif
|
||||||
try {
|
try {
|
||||||
ASSERT(is_valid_fspp_path(path), "has to be an absolute path");
|
ASSERT(is_valid_fspp_path(path), "has to be an absolute path");
|
||||||
// DokanY seems to call mkdir("/"). Ignore that
|
// DokanY seems to call mkdir("/"). Ignore that
|
||||||
if ("/" == path) {
|
if ("/" == path) {
|
||||||
#ifdef FSPP_LOG
|
#ifdef FSPP_LOG
|
||||||
LOG(DEBUG, "mkdir({}, {}): ignored", path.string(), mode);
|
LOG(DEBUG, "mkdir({}, {}): ignored", path, mode);
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +352,7 @@ int Fuse::rename(const bf::path &from, const bf::path &to) {
|
||||||
//TODO
|
//TODO
|
||||||
int Fuse::link(const bf::path &from, const bf::path &to) {
|
int Fuse::link(const bf::path &from, const bf::path &to) {
|
||||||
ThreadNameForDebugging _threadName("link");
|
ThreadNameForDebugging _threadName("link");
|
||||||
LOG(WARN, "NOT IMPLEMENTED: link({}, {})", from.string(), to.string());
|
LOG(WARN, "NOT IMPLEMENTED: link({}, {})", from, to);
|
||||||
//auto real_from = _impl->RootDir() / from;
|
//auto real_from = _impl->RootDir() / from;
|
||||||
//auto real_to = _impl->RootDir() / to;
|
//auto real_to = _impl->RootDir() / to;
|
||||||
//int retstat = ::link(real_from.string().c_str(), real_to.string().c_str());
|
//int retstat = ::link(real_from.string().c_str(), real_to.string().c_str());
|
||||||
|
|
|
@ -25,7 +25,8 @@ class Filesystem;
|
||||||
|
|
||||||
class Fuse final {
|
class Fuse final {
|
||||||
public:
|
public:
|
||||||
explicit Fuse(std::function<std::shared_ptr<Filesystem> ()> init);
|
explicit Fuse(std::function<std::shared_ptr<Filesystem> ()> init, std::string fstype, boost::optional<std::string> fsname);
|
||||||
|
~Fuse();
|
||||||
|
|
||||||
bool running() const;
|
bool running() const;
|
||||||
void stop();
|
void stop();
|
||||||
|
@ -70,7 +71,10 @@ private:
|
||||||
|
|
||||||
std::function<std::shared_ptr<Filesystem> ()> _init;
|
std::function<std::shared_ptr<Filesystem> ()> _init;
|
||||||
std::shared_ptr<Filesystem> _fs;
|
std::shared_ptr<Filesystem> _fs;
|
||||||
|
std::vector<char*> _argv;
|
||||||
std::atomic<bool> _running;
|
std::atomic<bool> _running;
|
||||||
|
std::string _fstype;
|
||||||
|
boost::optional<std::string> _fsname;
|
||||||
boost::optional<Context> _context;
|
boost::optional<Context> _context;
|
||||||
::uid_t uid;
|
::uid_t uid;
|
||||||
::gid_t gid;
|
::gid_t gid;
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
project (gitversion)
|
project (gitversion)
|
||||||
|
|
||||||
|
include(gitversion.cmake)
|
||||||
|
get_git_version(GIT_VERSION)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
gitversion.cpp
|
gitversion.cpp
|
||||||
versionstring.cpp
|
versionstring.cpp
|
||||||
|
@ -9,9 +12,6 @@ set(SOURCES
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} STATIC ${SOURCES})
|
add_library(${PROJECT_NAME} STATIC ${SOURCES})
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC boost)
|
target_link_libraries(${PROJECT_NAME} PUBLIC boost)
|
||||||
if (NOT DEFINED GIT_VERSION)
|
|
||||||
message(FATAL_ERROR "GIT_VERSION not defined")
|
|
||||||
endif()
|
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE GIT_VERSION_STRING="${GIT_VERSION}")
|
target_compile_definitions(${PROJECT_NAME} PRIVATE GIT_VERSION_STRING="${GIT_VERSION}")
|
||||||
target_add_boost(${PROJECT_NAME})
|
target_add_boost(${PROJECT_NAME})
|
||||||
target_enable_style_warnings(${PROJECT_NAME})
|
target_enable_style_warnings(${PROJECT_NAME})
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
include versioneer.py
|
||||||
|
include _version_source.py
|
||||||
|
include _version.py
|
|
@ -0,0 +1,487 @@
|
||||||
|
|
||||||
|
# This file helps to compute a version number in source trees obtained from
|
||||||
|
# git-archive tarball (such as those provided by githubs download-from-tag
|
||||||
|
# feature). Distribution tarballs (built by setup.py sdist) and build
|
||||||
|
# directories (produced by setup.py build) will contain a much shorter file
|
||||||
|
# that just contains the computed version number.
|
||||||
|
|
||||||
|
# This file is released into the public domain. Generated by
|
||||||
|
# versioneer-0.15+dev (https://github.com/warner/python-versioneer)
|
||||||
|
|
||||||
|
"""Git implementation of _version.py."""
|
||||||
|
|
||||||
|
import errno
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def get_keywords():
|
||||||
|
"""Get the keywords needed to look up the version information."""
|
||||||
|
# these strings will be replaced by git during git-archive.
|
||||||
|
# setup.py/versioneer.py will grep for the variable names, so they must
|
||||||
|
# each be defined on a line of their own. _version.py will just call
|
||||||
|
# get_keywords().
|
||||||
|
git_refnames = "$Format:%d$"
|
||||||
|
git_full = "$Format:%H$"
|
||||||
|
keywords = {"refnames": git_refnames, "full": git_full}
|
||||||
|
return keywords
|
||||||
|
|
||||||
|
|
||||||
|
class VersioneerConfig:
|
||||||
|
|
||||||
|
"""Container for Versioneer configuration parameters."""
|
||||||
|
|
||||||
|
|
||||||
|
def get_config():
|
||||||
|
"""Create, populate and return the VersioneerConfig() object."""
|
||||||
|
# these strings are filled in when 'setup.py versioneer' creates
|
||||||
|
# _version.py
|
||||||
|
cfg = VersioneerConfig()
|
||||||
|
cfg.VCS = "git"
|
||||||
|
cfg.style = "pep440"
|
||||||
|
cfg.tag_prefix = ""
|
||||||
|
cfg.parentdir_prefix = "cryfs-"
|
||||||
|
cfg.versionfile_source = "_version.py"
|
||||||
|
cfg.verbose = False
|
||||||
|
return cfg
|
||||||
|
|
||||||
|
|
||||||
|
class NotThisMethod(Exception):
|
||||||
|
|
||||||
|
"""Exception raised if a method is not valid for the current scenario."""
|
||||||
|
|
||||||
|
|
||||||
|
LONG_VERSION_PY = {}
|
||||||
|
HANDLERS = {}
|
||||||
|
|
||||||
|
|
||||||
|
def register_vcs_handler(vcs, method): # decorator
|
||||||
|
"""Decorator to mark a method as the handler for a particular VCS."""
|
||||||
|
def decorate(f):
|
||||||
|
"""Store f in HANDLERS[vcs][method]."""
|
||||||
|
if vcs not in HANDLERS:
|
||||||
|
HANDLERS[vcs] = {}
|
||||||
|
HANDLERS[vcs][method] = f
|
||||||
|
return f
|
||||||
|
return decorate
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False):
|
||||||
|
"""Call the given command(s)."""
|
||||||
|
assert isinstance(commands, list)
|
||||||
|
p = None
|
||||||
|
for c in commands:
|
||||||
|
try:
|
||||||
|
dispcmd = str([c] + args)
|
||||||
|
# remember shell=False, so use git.cmd on windows, not just git
|
||||||
|
p = subprocess.Popen([c] + args, cwd=cwd, stdout=subprocess.PIPE,
|
||||||
|
stderr=(subprocess.PIPE if hide_stderr
|
||||||
|
else None))
|
||||||
|
break
|
||||||
|
except EnvironmentError:
|
||||||
|
e = sys.exc_info()[1]
|
||||||
|
if e.errno == errno.ENOENT:
|
||||||
|
continue
|
||||||
|
if verbose:
|
||||||
|
print("unable to run %s" % dispcmd)
|
||||||
|
print(e)
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
if verbose:
|
||||||
|
print("unable to find command, tried %s" % (commands,))
|
||||||
|
return None
|
||||||
|
stdout = p.communicate()[0].strip()
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
stdout = stdout.decode()
|
||||||
|
if p.returncode != 0:
|
||||||
|
if verbose:
|
||||||
|
print("unable to run %s (error)" % dispcmd)
|
||||||
|
return None
|
||||||
|
return stdout
|
||||||
|
|
||||||
|
|
||||||
|
def versions_from_parentdir(parentdir_prefix, root, verbose):
|
||||||
|
"""Try to determine the version from the parent directory name.
|
||||||
|
|
||||||
|
Source tarballs conventionally unpack into a directory that includes
|
||||||
|
both the project name and a version string.
|
||||||
|
"""
|
||||||
|
# -- (MESSMER) CHANGED FOLLOWING LINE TO LOOK IN ../.. instead of . --
|
||||||
|
dirname = os.path.basename(os.path.abspath(os.path.join(os.path.join(root, '..'), '..')))
|
||||||
|
if not dirname.startswith(parentdir_prefix):
|
||||||
|
if verbose:
|
||||||
|
print("guessing rootdir is '%s', but '%s' doesn't start with "
|
||||||
|
"prefix '%s'" % (root, dirname, parentdir_prefix))
|
||||||
|
raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
|
||||||
|
return {"version": dirname[len(parentdir_prefix):],
|
||||||
|
"full-revisionid": None,
|
||||||
|
"dirty": False, "error": None}
|
||||||
|
|
||||||
|
|
||||||
|
@register_vcs_handler("git", "get_keywords")
|
||||||
|
def git_get_keywords(versionfile_abs):
|
||||||
|
"""Extract version information from the given file."""
|
||||||
|
# the code embedded in _version.py can just fetch the value of these
|
||||||
|
# keywords. When used from setup.py, we don't want to import _version.py,
|
||||||
|
# so we do it with a regexp instead. This function is not used from
|
||||||
|
# _version.py.
|
||||||
|
keywords = {}
|
||||||
|
try:
|
||||||
|
f = open(versionfile_abs, "r")
|
||||||
|
for line in f.readlines():
|
||||||
|
if line.strip().startswith("git_refnames ="):
|
||||||
|
mo = re.search(r'=\s*"(.*)"', line)
|
||||||
|
if mo:
|
||||||
|
keywords["refnames"] = mo.group(1)
|
||||||
|
if line.strip().startswith("git_full ="):
|
||||||
|
mo = re.search(r'=\s*"(.*)"', line)
|
||||||
|
if mo:
|
||||||
|
keywords["full"] = mo.group(1)
|
||||||
|
f.close()
|
||||||
|
except EnvironmentError:
|
||||||
|
pass
|
||||||
|
return keywords
|
||||||
|
|
||||||
|
|
||||||
|
@register_vcs_handler("git", "keywords")
|
||||||
|
def git_versions_from_keywords(keywords, tag_prefix, verbose):
|
||||||
|
"""Get version information from git keywords."""
|
||||||
|
if not keywords:
|
||||||
|
raise NotThisMethod("no keywords at all, weird")
|
||||||
|
refnames = keywords["refnames"].strip()
|
||||||
|
if refnames.startswith("$Format"):
|
||||||
|
if verbose:
|
||||||
|
print("keywords are unexpanded, not using")
|
||||||
|
raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
|
||||||
|
refs = set([r.strip() for r in refnames.strip("()").split(",")])
|
||||||
|
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
|
||||||
|
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
|
||||||
|
TAG = "tag: "
|
||||||
|
tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
|
||||||
|
if not tags:
|
||||||
|
# Either we're using git < 1.8.3, or there really are no tags. We use
|
||||||
|
# a heuristic: assume all version tags have a digit. The old git %d
|
||||||
|
# expansion behaves like git log --decorate=short and strips out the
|
||||||
|
# refs/heads/ and refs/tags/ prefixes that would let us distinguish
|
||||||
|
# between branches and tags. By ignoring refnames without digits, we
|
||||||
|
# filter out many common branch names like "release" and
|
||||||
|
# "stabilization", as well as "HEAD" and "master".
|
||||||
|
tags = set([r for r in refs if re.search(r'\d', r)])
|
||||||
|
if verbose:
|
||||||
|
print("discarding '%s', no digits" % ",".join(refs-tags))
|
||||||
|
if verbose:
|
||||||
|
print("likely tags: %s" % ",".join(sorted(tags)))
|
||||||
|
for ref in sorted(tags):
|
||||||
|
# sorting will prefer e.g. "2.0" over "2.0rc1"
|
||||||
|
if ref.startswith(tag_prefix):
|
||||||
|
r = ref[len(tag_prefix):]
|
||||||
|
if verbose:
|
||||||
|
print("picking %s" % r)
|
||||||
|
return {"version": r,
|
||||||
|
"full-revisionid": keywords["full"].strip(),
|
||||||
|
"dirty": False, "error": None
|
||||||
|
}
|
||||||
|
# no suitable tags, so version is "0+unknown", but full hex is still there
|
||||||
|
if verbose:
|
||||||
|
print("no suitable tags, using unknown + full revision id")
|
||||||
|
return {"version": "0+unknown",
|
||||||
|
"full-revisionid": keywords["full"].strip(),
|
||||||
|
"dirty": False, "error": "no suitable tags"}
|
||||||
|
|
||||||
|
|
||||||
|
@register_vcs_handler("git", "pieces_from_vcs")
|
||||||
|
def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
|
||||||
|
"""Get version from 'git describe' in the root of the source tree.
|
||||||
|
|
||||||
|
This only gets called if the git-archive 'subst' keywords were *not*
|
||||||
|
expanded, and _version.py hasn't already been rewritten with a short
|
||||||
|
version string, meaning we're inside a checked out source tree.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(os.path.join(root, ".git")):
|
||||||
|
if verbose:
|
||||||
|
print("no .git in %s" % root)
|
||||||
|
raise NotThisMethod("no .git directory")
|
||||||
|
|
||||||
|
GITS = ["git"]
|
||||||
|
if sys.platform == "win32":
|
||||||
|
GITS = ["git.cmd", "git.exe"]
|
||||||
|
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
|
||||||
|
# if there isn't one, this yields HEX[-dirty] (no NUM)
|
||||||
|
describe_out = run_command(GITS, ["describe", "--tags", "--dirty",
|
||||||
|
"--always", "--long",
|
||||||
|
"--match", "%s*" % tag_prefix],
|
||||||
|
cwd=root)
|
||||||
|
# --long was added in git-1.5.5
|
||||||
|
if describe_out is None:
|
||||||
|
raise NotThisMethod("'git describe' failed")
|
||||||
|
describe_out = describe_out.strip()
|
||||||
|
full_out = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
|
||||||
|
if full_out is None:
|
||||||
|
raise NotThisMethod("'git rev-parse' failed")
|
||||||
|
full_out = full_out.strip()
|
||||||
|
|
||||||
|
pieces = {}
|
||||||
|
pieces["long"] = full_out
|
||||||
|
pieces["short"] = full_out[:7] # maybe improved later
|
||||||
|
pieces["error"] = None
|
||||||
|
|
||||||
|
# parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
|
||||||
|
# TAG might have hyphens.
|
||||||
|
git_describe = describe_out
|
||||||
|
|
||||||
|
# look for -dirty suffix
|
||||||
|
dirty = git_describe.endswith("-dirty")
|
||||||
|
pieces["dirty"] = dirty
|
||||||
|
if dirty:
|
||||||
|
git_describe = git_describe[:git_describe.rindex("-dirty")]
|
||||||
|
|
||||||
|
# now we have TAG-NUM-gHEX or HEX
|
||||||
|
|
||||||
|
if "-" in git_describe:
|
||||||
|
# TAG-NUM-gHEX
|
||||||
|
mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
|
||||||
|
if not mo:
|
||||||
|
# unparseable. Maybe git-describe is misbehaving?
|
||||||
|
pieces["error"] = ("unable to parse git-describe output: '%s'"
|
||||||
|
% describe_out)
|
||||||
|
return pieces
|
||||||
|
|
||||||
|
# tag
|
||||||
|
full_tag = mo.group(1)
|
||||||
|
if not full_tag.startswith(tag_prefix):
|
||||||
|
if verbose:
|
||||||
|
fmt = "tag '%s' doesn't start with prefix '%s'"
|
||||||
|
print(fmt % (full_tag, tag_prefix))
|
||||||
|
pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
|
||||||
|
% (full_tag, tag_prefix))
|
||||||
|
return pieces
|
||||||
|
pieces["closest-tag"] = full_tag[len(tag_prefix):]
|
||||||
|
|
||||||
|
# distance: number of commits since tag
|
||||||
|
pieces["distance"] = int(mo.group(2))
|
||||||
|
|
||||||
|
# commit: short hex revision ID
|
||||||
|
pieces["short"] = mo.group(3)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# HEX: no tags
|
||||||
|
pieces["closest-tag"] = None
|
||||||
|
count_out = run_command(GITS, ["rev-list", "HEAD", "--count"],
|
||||||
|
cwd=root)
|
||||||
|
pieces["distance"] = int(count_out) # total number of commits
|
||||||
|
|
||||||
|
return pieces
|
||||||
|
|
||||||
|
|
||||||
|
def plus_or_dot(pieces):
|
||||||
|
"""Return a + if we don't already have one, else return a ."""
|
||||||
|
if "+" in pieces.get("closest-tag", ""):
|
||||||
|
return "."
|
||||||
|
return "+"
|
||||||
|
|
||||||
|
|
||||||
|
def render_pep440(pieces):
|
||||||
|
"""Build up version string, with post-release "local version identifier".
|
||||||
|
|
||||||
|
Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
|
||||||
|
get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
|
||||||
|
"""
|
||||||
|
if pieces["closest-tag"]:
|
||||||
|
rendered = pieces["closest-tag"]
|
||||||
|
if pieces["distance"] or pieces["dirty"]:
|
||||||
|
rendered += plus_or_dot(pieces)
|
||||||
|
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += ".dirty"
|
||||||
|
else:
|
||||||
|
# exception #1
|
||||||
|
rendered = "0+untagged.%d.g%s" % (pieces["distance"],
|
||||||
|
pieces["short"])
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += ".dirty"
|
||||||
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
|
def render_pep440_pre(pieces):
|
||||||
|
"""TAG[.post.devDISTANCE] -- No -dirty.
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
1: no tags. 0.post.devDISTANCE
|
||||||
|
"""
|
||||||
|
if pieces["closest-tag"]:
|
||||||
|
rendered = pieces["closest-tag"]
|
||||||
|
if pieces["distance"]:
|
||||||
|
rendered += ".post.dev%d" % pieces["distance"]
|
||||||
|
else:
|
||||||
|
# exception #1
|
||||||
|
rendered = "0.post.dev%d" % pieces["distance"]
|
||||||
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
|
def render_pep440_post(pieces):
|
||||||
|
"""TAG[.postDISTANCE[.dev0]+gHEX] .
|
||||||
|
|
||||||
|
The ".dev0" means dirty. Note that .dev0 sorts backwards
|
||||||
|
(a dirty tree will appear "older" than the corresponding clean one),
|
||||||
|
but you shouldn't be releasing software with -dirty anyways.
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
1: no tags. 0.postDISTANCE[.dev0]
|
||||||
|
"""
|
||||||
|
if pieces["closest-tag"]:
|
||||||
|
rendered = pieces["closest-tag"]
|
||||||
|
if pieces["distance"] or pieces["dirty"]:
|
||||||
|
rendered += ".post%d" % pieces["distance"]
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += ".dev0"
|
||||||
|
rendered += plus_or_dot(pieces)
|
||||||
|
rendered += "g%s" % pieces["short"]
|
||||||
|
else:
|
||||||
|
# exception #1
|
||||||
|
rendered = "0.post%d" % pieces["distance"]
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += ".dev0"
|
||||||
|
rendered += "+g%s" % pieces["short"]
|
||||||
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
|
def render_pep440_old(pieces):
|
||||||
|
"""TAG[.postDISTANCE[.dev0]] .
|
||||||
|
|
||||||
|
The ".dev0" means dirty.
|
||||||
|
|
||||||
|
Eexceptions:
|
||||||
|
1: no tags. 0.postDISTANCE[.dev0]
|
||||||
|
"""
|
||||||
|
if pieces["closest-tag"]:
|
||||||
|
rendered = pieces["closest-tag"]
|
||||||
|
if pieces["distance"] or pieces["dirty"]:
|
||||||
|
rendered += ".post%d" % pieces["distance"]
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += ".dev0"
|
||||||
|
else:
|
||||||
|
# exception #1
|
||||||
|
rendered = "0.post%d" % pieces["distance"]
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += ".dev0"
|
||||||
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
|
def render_git_describe(pieces):
|
||||||
|
"""TAG[-DISTANCE-gHEX][-dirty].
|
||||||
|
|
||||||
|
Like 'git describe --tags --dirty --always'.
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
1: no tags. HEX[-dirty] (note: no 'g' prefix)
|
||||||
|
"""
|
||||||
|
if pieces["closest-tag"]:
|
||||||
|
rendered = pieces["closest-tag"]
|
||||||
|
if pieces["distance"]:
|
||||||
|
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
|
||||||
|
else:
|
||||||
|
# exception #1
|
||||||
|
rendered = pieces["short"]
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += "-dirty"
|
||||||
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
|
def render_git_describe_long(pieces):
|
||||||
|
"""TAG-DISTANCE-gHEX[-dirty].
|
||||||
|
|
||||||
|
Like 'git describe --tags --dirty --always -long'.
|
||||||
|
The distance/hash is unconditional.
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
1: no tags. HEX[-dirty] (note: no 'g' prefix)
|
||||||
|
"""
|
||||||
|
if pieces["closest-tag"]:
|
||||||
|
rendered = pieces["closest-tag"]
|
||||||
|
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
|
||||||
|
else:
|
||||||
|
# exception #1
|
||||||
|
rendered = pieces["short"]
|
||||||
|
if pieces["dirty"]:
|
||||||
|
rendered += "-dirty"
|
||||||
|
return rendered
|
||||||
|
|
||||||
|
|
||||||
|
def render(pieces, style):
|
||||||
|
"""Render the given version pieces into the requested style."""
|
||||||
|
if pieces["error"]:
|
||||||
|
return {"version": "unknown",
|
||||||
|
"full-revisionid": pieces.get("long"),
|
||||||
|
"dirty": None,
|
||||||
|
"error": pieces["error"]}
|
||||||
|
|
||||||
|
if not style or style == "default":
|
||||||
|
style = "pep440" # the default
|
||||||
|
|
||||||
|
if style == "pep440":
|
||||||
|
rendered = render_pep440(pieces)
|
||||||
|
elif style == "pep440-pre":
|
||||||
|
rendered = render_pep440_pre(pieces)
|
||||||
|
elif style == "pep440-post":
|
||||||
|
rendered = render_pep440_post(pieces)
|
||||||
|
elif style == "pep440-old":
|
||||||
|
rendered = render_pep440_old(pieces)
|
||||||
|
elif style == "git-describe":
|
||||||
|
rendered = render_git_describe(pieces)
|
||||||
|
elif style == "git-describe-long":
|
||||||
|
rendered = render_git_describe_long(pieces)
|
||||||
|
else:
|
||||||
|
raise ValueError("unknown style '%s'" % style)
|
||||||
|
|
||||||
|
return {"version": rendered, "full-revisionid": pieces["long"],
|
||||||
|
"dirty": pieces["dirty"], "error": None}
|
||||||
|
|
||||||
|
|
||||||
|
def get_versions():
|
||||||
|
"""Get version information or return default if unable to do so."""
|
||||||
|
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
|
||||||
|
# __file__, we can work backwards from there to the root. Some
|
||||||
|
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
|
||||||
|
# case we can only use expanded keywords.
|
||||||
|
|
||||||
|
cfg = get_config()
|
||||||
|
verbose = cfg.verbose
|
||||||
|
|
||||||
|
try:
|
||||||
|
return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
|
||||||
|
verbose)
|
||||||
|
except NotThisMethod:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
root = os.path.realpath(__file__)
|
||||||
|
# versionfile_source is the relative path from the top of the source
|
||||||
|
# tree (where the .git directory might live) to this file. Invert
|
||||||
|
# this to find the root from __file__.
|
||||||
|
for i in cfg.versionfile_source.split('/'):
|
||||||
|
root = os.path.dirname(root)
|
||||||
|
except NameError:
|
||||||
|
return {"version": "0+unknown", "full-revisionid": None,
|
||||||
|
"dirty": None,
|
||||||
|
"error": "unable to find root of source tree"}
|
||||||
|
|
||||||
|
try:
|
||||||
|
pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
|
||||||
|
return render(pieces, cfg.style)
|
||||||
|
except NotThisMethod:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
if cfg.parentdir_prefix:
|
||||||
|
return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
|
||||||
|
except NotThisMethod:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return {"version": "0+unknown", "full-revisionid": None,
|
||||||
|
"dirty": None,
|
||||||
|
"error": "unable to compute version"}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import versioneer
|
||||||
|
|
||||||
|
print(versioneer.get_version())
|
|
@ -0,0 +1,18 @@
|
||||||
|
set(DIR_OF_GITVERSION_TOOL "${CMAKE_CURRENT_LIST_DIR}" CACHE INTERNAL "DIR_OF_GITVERSION_TOOL")
|
||||||
|
|
||||||
|
function (get_git_version OUTPUT_VARIABLE)
|
||||||
|
EXECUTE_PROCESS(COMMAND python3 ${DIR_OF_GITVERSION_TOOL}/getversion.py
|
||||||
|
WORKING_DIRECTORY ${DIR_OF_GITVERSION_TOOL}
|
||||||
|
OUTPUT_VARIABLE VERSION
|
||||||
|
ERROR_VARIABLE error
|
||||||
|
RESULT_VARIABLE result)
|
||||||
|
STRING(STRIP "${VERSION}" STRIPPED_VERSION)
|
||||||
|
SET(${OUTPUT_VARIABLE} "${STRIPPED_VERSION}" CACHE INTERNAL "${OUTPUT_VARIABLE}")
|
||||||
|
MESSAGE(STATUS "Building version ${${OUTPUT_VARIABLE}}")
|
||||||
|
IF(NOT ${result} EQUAL 0)
|
||||||
|
MESSAGE(FATAL_ERROR "Error running versioneer. Return code is: ${result}, error message is: ${error}")
|
||||||
|
ENDIF()
|
||||||
|
IF("${STRIPPED_VERSION}" STREQUAL "0+unknown")
|
||||||
|
MESSAGE(FATAL_ERROR "Unable to find git version information. Please build directly from a git repository (i.e. after git clone).")
|
||||||
|
ENDIF()
|
||||||
|
endfunction(get_git_version)
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
# See the docstring in versioneer.py for instructions. Note that you must
|
||||||
|
# re-run 'versioneer.py setup' after changing this section, and commit the
|
||||||
|
# resulting files.
|
||||||
|
|
||||||
|
[versioneer]
|
||||||
|
VCS = git
|
||||||
|
style = pep440
|
||||||
|
versionfile_source = _version.py
|
||||||
|
versionfile_build = None
|
||||||
|
tag_prefix =
|
||||||
|
parentdir_prefix = cryfs-
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from setuptools import setup
|
||||||
|
import versioneer
|
||||||
|
|
||||||
|
setup(name='git-version',
|
||||||
|
version=versioneer.get_version(),
|
||||||
|
cmdclass=versioneer.get_cmdclass(),
|
||||||
|
description='Make git version information (e.g. git tag name, git commit id, ...) available to C++ source files.',
|
||||||
|
author='Sebastian Messmer',
|
||||||
|
author_email='messmer@cryfs.org',
|
||||||
|
license='LGPLv3'
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,10 @@
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
jlong cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalSateDir, jbyteArray jpassword,
|
jlong cryfs_init(JNIEnv* env, jstring jbaseDir, jstring jlocalSateDir, jbyteArray jpassword, jboolean createBaseDir, jstring jcipher);
|
||||||
jbyteArray jgivenHash, jobject returnedHash, jboolean createBaseDir,
|
|
||||||
jstring jcipher, jobject jerrorCode);
|
|
||||||
jboolean cryfs_change_encryption_key(JNIEnv *env,
|
|
||||||
jstring jbaseDir, jstring jlocalStateDir,
|
|
||||||
jbyteArray jcurrentPassword, jbyteArray jgivenHash,
|
|
||||||
jbyteArray jnewPassword, jobject jreturnedHash);
|
|
||||||
jlong cryfs_create(JNIEnv* env, jlong fusePtr, jstring jpath, mode_t mode);
|
jlong cryfs_create(JNIEnv* env, jlong fusePtr, jstring jpath, mode_t mode);
|
||||||
jlong cryfs_open(JNIEnv* env, jlong fusePtr, jstring jpath, jint flags);
|
jlong cryfs_open(JNIEnv* env, jlong fusePtr, jstring jpath, jint flags);
|
||||||
jint cryfs_read(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong fileOffset, jbyteArray buffer, jlong dstOffset, jlong length);
|
jint cryfs_read(JNIEnv* env, jlong fusePtr, jlong fileHandle, jbyteArray jbuffer, jlong offset);
|
||||||
jint cryfs_write(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong fileOffset, jbyteArray buffer, jlong srcOffset, jlong length);
|
jint cryfs_write(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong offset, jbyteArray jbuffer, jint size);
|
||||||
jint cryfs_truncate(JNIEnv* env, jlong fusePtr, jstring jpath, jlong size);
|
jint cryfs_truncate(JNIEnv* env, jlong fusePtr, jstring jpath, jlong size);
|
||||||
jint cryfs_unlink(JNIEnv* env, jlong fusePtr, jstring jpath);
|
jint cryfs_unlink(JNIEnv* env, jlong fusePtr, jstring jpath);
|
||||||
jint cryfs_release(jlong fusePtr, jlong fileHandle);
|
jint cryfs_release(jlong fusePtr, jlong fileHandle);
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <cryfs-cli/Cli.h>
|
#include <cryfs-cli/Cli.h>
|
||||||
#include <fspp/fuse/Fuse.h>
|
#include <fspp/fuse/Fuse.h>
|
||||||
#include <cryfs/impl/CryfsException.h>
|
|
||||||
#include <cryfs/impl/config/CryKeyProvider.h>
|
|
||||||
#include <cryfs/impl/config/CryDirectKeyProvider.h>
|
|
||||||
#include <cryfs/impl/config/CryPresetPasswordBasedKeyProvider.h>
|
|
||||||
|
|
||||||
|
using std::unique_ptr;
|
||||||
|
using std::make_unique;
|
||||||
using boost::none;
|
using boost::none;
|
||||||
using cpputils::Random;
|
using cpputils::Random;
|
||||||
using cpputils::SCrypt;
|
using cpputils::SCrypt;
|
||||||
|
@ -15,21 +13,7 @@ using fspp::fuse::Fuse;
|
||||||
|
|
||||||
std::set<jlong> validFusePtrs;
|
std::set<jlong> validFusePtrs;
|
||||||
|
|
||||||
jfieldID getValueField(JNIEnv* env, jobject object) {
|
extern "C" jlong cryfs_init(JNIEnv* env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpassword, jboolean createBaseDir, jstring jcipher) {
|
||||||
return env->GetFieldID(env->GetObjectClass(object), "value", "Ljava/lang/Object;");
|
|
||||||
}
|
|
||||||
|
|
||||||
void setReturnedPasswordHash(JNIEnv* env, jobject jreturnedHash, const SizedData& returnedHash) {
|
|
||||||
jbyteArray jpasswordHash = env->NewByteArray(returnedHash.size);
|
|
||||||
env->SetByteArrayRegion(jpasswordHash, 0, returnedHash.size, reinterpret_cast<const jbyte*>(returnedHash.data));
|
|
||||||
delete[] returnedHash.data;
|
|
||||||
env->SetObjectField(jreturnedHash, getValueField(env, jreturnedHash), jpasswordHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" jlong
|
|
||||||
cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpassword,
|
|
||||||
jbyteArray jgivenHash, jobject jreturnedHash, jboolean createBaseDir,
|
|
||||||
jstring jcipher, jobject jerrorCode) {
|
|
||||||
const char* baseDir = env->GetStringUTFChars(jbaseDir, NULL);
|
const char* baseDir = env->GetStringUTFChars(jbaseDir, NULL);
|
||||||
const char* localStateDir = env->GetStringUTFChars(jlocalStateDir, NULL);
|
const char* localStateDir = env->GetStringUTFChars(jlocalStateDir, NULL);
|
||||||
boost::optional<string> cipher = none;
|
boost::optional<string> cipher = none;
|
||||||
|
@ -38,44 +22,16 @@ cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpa
|
||||||
cipher = boost::optional<string>(cipherName);
|
cipher = boost::optional<string>(cipherName);
|
||||||
env->ReleaseStringUTFChars(jcipher, cipherName);
|
env->ReleaseStringUTFChars(jcipher, cipherName);
|
||||||
}
|
}
|
||||||
auto &keyGenerator = Random::OSRandom();
|
auto &keyGenerator = Random::OSRandom();
|
||||||
ProgramOptions options = ProgramOptions(baseDir, none, localStateDir, false, false, createBaseDir, cipher, none, false, none);
|
ProgramOptions options = ProgramOptions(baseDir, none, localStateDir, false, false, createBaseDir, cipher, none, false, none);
|
||||||
|
char* password = reinterpret_cast<char*>(env->GetByteArrayElements(jpassword, NULL));
|
||||||
|
|
||||||
|
Fuse* fuse = Cli(keyGenerator, SCrypt::DefaultSettings).initFilesystem(options, make_unique<string>(password));
|
||||||
|
|
||||||
|
env->ReleaseByteArrayElements(jpassword, reinterpret_cast<jbyte*>(password), 0);
|
||||||
env->ReleaseStringUTFChars(jbaseDir, baseDir);
|
env->ReleaseStringUTFChars(jbaseDir, baseDir);
|
||||||
env->ReleaseStringUTFChars(jlocalStateDir, localStateDir);
|
env->ReleaseStringUTFChars(jlocalStateDir, localStateDir);
|
||||||
struct SizedData returnedHash;
|
|
||||||
struct Cli::Credentials credentials;
|
|
||||||
credentials.returnedHash = nullptr;
|
|
||||||
if (jpassword == NULL) {
|
|
||||||
credentials.password = none;
|
|
||||||
credentials.givenHash.data = reinterpret_cast<unsigned char*>(env->GetByteArrayElements(jgivenHash, NULL));
|
|
||||||
credentials.givenHash.size = env->GetArrayLength(jgivenHash);
|
|
||||||
} else {
|
|
||||||
jbyte* password = env->GetByteArrayElements(jpassword, NULL);
|
|
||||||
credentials.password = string(reinterpret_cast<const char*>(password), env->GetArrayLength(jpassword));
|
|
||||||
env->ReleaseByteArrayElements(jpassword, password, 0);
|
|
||||||
if (jreturnedHash != NULL) {
|
|
||||||
credentials.returnedHash = &returnedHash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Fuse* fuse = 0;
|
|
||||||
try {
|
|
||||||
fuse = Cli(keyGenerator, SCrypt::DefaultSettings).initFilesystem(options, credentials);
|
|
||||||
} catch (const cryfs::CryfsException &e) {
|
|
||||||
int errorCode = static_cast<int>(e.errorCode());
|
|
||||||
if (e.what() != string()) {
|
|
||||||
LOG(cpputils::logging::ERR, "Error {}: {}", errorCode, e.what());
|
|
||||||
}
|
|
||||||
jclass integerClass = env->FindClass("java/lang/Integer");
|
|
||||||
jobject integer = env->NewObject(integerClass, env->GetMethodID(integerClass, "<init>", "(I)V"), errorCode);
|
|
||||||
env->SetObjectField(jerrorCode, getValueField(env, jerrorCode), integer);
|
|
||||||
}
|
|
||||||
if (jpassword == NULL) {
|
|
||||||
env->ReleaseByteArrayElements(jgivenHash, reinterpret_cast<jbyte*>(credentials.givenHash.data), 0);
|
|
||||||
}
|
|
||||||
if (credentials.returnedHash != nullptr) {
|
|
||||||
setReturnedPasswordHash(env, jreturnedHash, returnedHash);
|
|
||||||
}
|
|
||||||
jlong fusePtr = reinterpret_cast<jlong>(fuse);
|
jlong fusePtr = reinterpret_cast<jlong>(fuse);
|
||||||
if (fusePtr != 0) {
|
if (fusePtr != 0) {
|
||||||
validFusePtrs.insert(fusePtr);
|
validFusePtrs.insert(fusePtr);
|
||||||
|
@ -83,55 +39,6 @@ cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpa
|
||||||
return fusePtr;
|
return fusePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" jboolean cryfs_change_encryption_key(JNIEnv* env, jstring jbaseDir, jstring jlocalStateDir,
|
|
||||||
jbyteArray jcurrentPassword, jbyteArray jgivenHash,
|
|
||||||
jbyteArray jnewPassword, jobject jreturnedHash) {
|
|
||||||
using namespace cryfs;
|
|
||||||
|
|
||||||
const char* baseDir = env->GetStringUTFChars(jbaseDir, NULL);
|
|
||||||
const char* localStateDir = env->GetStringUTFChars(jlocalStateDir, NULL);
|
|
||||||
|
|
||||||
struct SizedData givenHash;
|
|
||||||
std::unique_ptr<CryKeyProvider> currentKeyProvider;
|
|
||||||
if (jcurrentPassword == NULL) {
|
|
||||||
givenHash.data = reinterpret_cast<unsigned char*>(env->GetByteArrayElements(jgivenHash, NULL));
|
|
||||||
givenHash.size = env->GetArrayLength(jgivenHash);
|
|
||||||
currentKeyProvider = std::make_unique<CryDirectKeyProvider>(givenHash);
|
|
||||||
} else {
|
|
||||||
jbyte* currentPassword = env->GetByteArrayElements(jcurrentPassword, NULL);
|
|
||||||
currentKeyProvider = std::make_unique<CryPresetPasswordBasedKeyProvider>(
|
|
||||||
string(reinterpret_cast<const char*>(currentPassword), env->GetArrayLength(jcurrentPassword)),
|
|
||||||
cpputils::make_unique_ref<SCrypt>(SCrypt::DefaultSettings),
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
env->ReleaseByteArrayElements(jcurrentPassword, currentPassword, 0);
|
|
||||||
}
|
|
||||||
struct SizedData returnedHash = {nullptr, 0};
|
|
||||||
jbyte* newPassword = env->GetByteArrayElements(jnewPassword, NULL);
|
|
||||||
cpputils::unique_ref<CryKeyProvider> newKeyProvider = cpputils::make_unique_ref<CryPresetPasswordBasedKeyProvider>(
|
|
||||||
string(reinterpret_cast<const char*>(newPassword), env->GetArrayLength(jnewPassword)),
|
|
||||||
cpputils::make_unique_ref<SCrypt>(SCrypt::DefaultSettings),
|
|
||||||
jreturnedHash == NULL ? nullptr : &returnedHash
|
|
||||||
);
|
|
||||||
env->ReleaseByteArrayElements(jnewPassword, newPassword, 0);
|
|
||||||
CryConfigLoader configLoader = CryConfigLoader(
|
|
||||||
Random::OSRandom(), std::move(*cpputils::nullcheck(std::move(currentKeyProvider))),
|
|
||||||
LocalStateDir(localStateDir), none, none, none
|
|
||||||
);
|
|
||||||
env->ReleaseStringUTFChars(jlocalStateDir, localStateDir);
|
|
||||||
|
|
||||||
auto result = configLoader.changeEncryptionKey(boost::filesystem::path(baseDir) / "cryfs.config", false, false, std::move(newKeyProvider));
|
|
||||||
|
|
||||||
if (jcurrentPassword == NULL) {
|
|
||||||
env->ReleaseByteArrayElements(jgivenHash, reinterpret_cast<jbyte*>(givenHash.data), 0);
|
|
||||||
}
|
|
||||||
env->ReleaseStringUTFChars(jbaseDir, baseDir);
|
|
||||||
if (returnedHash.data != nullptr) {
|
|
||||||
setReturnedPasswordHash(env, jreturnedHash, returnedHash);
|
|
||||||
}
|
|
||||||
return result == none;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" jlong cryfs_create(JNIEnv* env, jlong fusePtr, jstring jpath, mode_t mode) {
|
extern "C" jlong cryfs_create(JNIEnv* env, jlong fusePtr, jstring jpath, mode_t mode) {
|
||||||
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
|
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
|
||||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||||
|
@ -162,21 +69,22 @@ extern "C" jlong cryfs_open(JNIEnv* env, jlong fusePtr, jstring jpath, jint flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" jint cryfs_read(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong fileOffset, jbyteArray jbuffer, jlong dstOffset, jlong length) {
|
extern "C" jint cryfs_read(JNIEnv* env, jlong fusePtr, jlong fileHandle, jbyteArray jbuffer, jlong offset) {
|
||||||
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
|
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
|
||||||
|
const jsize size = env->GetArrayLength(jbuffer);
|
||||||
char* buff = reinterpret_cast<char*>(env->GetByteArrayElements(jbuffer, NULL));
|
char* buff = reinterpret_cast<char*>(env->GetByteArrayElements(jbuffer, NULL));
|
||||||
|
|
||||||
int result = fuse->read(buff+dstOffset, length, fileOffset, fileHandle);
|
int result = fuse->read(buff, size, offset, fileHandle);
|
||||||
|
|
||||||
env->ReleaseByteArrayElements(jbuffer, reinterpret_cast<jbyte*>(buff), 0);
|
env->ReleaseByteArrayElements(jbuffer, reinterpret_cast<jbyte*>(buff), 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" jint cryfs_write(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong fileOffset, jbyteArray jbuffer, jlong srcOffset, jlong length) {
|
extern "C" jint cryfs_write(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong offset, jbyteArray jbuffer, jint size) {
|
||||||
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
|
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
|
||||||
char* buff = reinterpret_cast<char*>(env->GetByteArrayElements(jbuffer, NULL));
|
char* buff = reinterpret_cast<char*>(env->GetByteArrayElements(jbuffer, NULL));
|
||||||
|
|
||||||
int result = fuse->write(buff+srcOffset, length, fileOffset, fileHandle);
|
int result = fuse->write(buff, size, offset, fileHandle);
|
||||||
|
|
||||||
env->ReleaseByteArrayElements(jbuffer, reinterpret_cast<jbyte*>(buff), 0);
|
env->ReleaseByteArrayElements(jbuffer, reinterpret_cast<jbyte*>(buff), 0);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c6012c576e30ff6000ddab0988d59bad849200ce
|
Subproject commit 0e12fbd30cb70b668a117c0913a303acfdaae04f
|
|
@ -1146,7 +1146,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.1" AND USE_OPENMP)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# If OpenMP wasn't found, try if we can find it in the default Homebrew location (Intel Macs)
|
# If OpenMP wasn't found, try if we can find it in the default Homebrew location
|
||||||
if((NOT OPENMP_FOUND) AND (NOT OPENMP_CXX_FOUND) AND EXISTS "/usr/local/opt/libomp/lib/libomp.dylib")
|
if((NOT OPENMP_FOUND) AND (NOT OPENMP_CXX_FOUND) AND EXISTS "/usr/local/opt/libomp/lib/libomp.dylib")
|
||||||
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
|
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
|
||||||
set(OpenMP_CXX_LIB_NAMES omp)
|
set(OpenMP_CXX_LIB_NAMES omp)
|
||||||
|
@ -1154,23 +1154,9 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.1" AND USE_OPENMP)
|
||||||
|
|
||||||
find_package(OpenMP)
|
find_package(OpenMP)
|
||||||
if (OPENMP_FOUND OR OPENMP_CXX_FOUND)
|
if (OPENMP_FOUND OR OPENMP_CXX_FOUND)
|
||||||
message(STATUS "OpenMP: Found libomp in homebrew default location for Intel Macs.")
|
message(STATUS "OpenMP: Found libomp in homebrew default location.")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "OpenMP: Didn't find libomp. Tried homebrew default location for Intel Macs but also didn't find it.")
|
message(FATAL_ERROR "OpenMP: Didn't find libomp. Tried homebrew default location but also didn't find it.")
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# If OpenMP wasn't found, try if we can find it in the default Homebrew location (Apple Silicon Macs)
|
|
||||||
if((NOT OPENMP_FOUND) AND (NOT OPENMP_CXX_FOUND) AND EXISTS "/opt/homebrew/opt/libomp/lib/libomp.dylib")
|
|
||||||
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/opt/homebrew/opt/libomp/include")
|
|
||||||
set(OpenMP_CXX_LIB_NAMES omp)
|
|
||||||
set(OpenMP_omp_LIBRARY /opt/homebrew/opt/libomp/lib/libomp.dylib)
|
|
||||||
|
|
||||||
find_package(OpenMP)
|
|
||||||
if (OPENMP_FOUND OR OPENMP_CXX_FOUND)
|
|
||||||
message(STATUS "OpenMP: Found libomp in homebrew default location for Apple Silicon Macs.")
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "OpenMP: Didn't find libomp. Tried homebrew default location for Apple Silicon Macs but also didn't find it.")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7e635fca68d014934b4af8a1cf874f63989352b7
|
Subproject commit a26e174b367a60a51f0be83a81d6d066330cdd8f
|
Loading…
Reference in New Issue