Compare commits

..

15 Commits

Author SHA1 Message Date
Matéo Duparc 35a2198ac9
libcyfs REAMDE 2022-06-26 12:58:01 +02:00
Matéo Duparc 267fb40fe7
Clean JNI library 2022-06-25 21:32:28 +02:00
Matéo Duparc f03d39433c
Cleaning 2022-06-25 16:57:50 +02:00
Matéo Duparc 9c19680b55
Remove range-v3 dependencies 2022-06-24 23:01:05 +02:00
Matéo Duparc fb593c468c
Switch to boost 1.77.0 2022-06-24 19:52:59 +02:00
Matéo Duparc ac2b8a615b
Fix boost build 2022-06-23 19:41:45 +02:00
Matéo Duparc f89ac70d59
Fix vendor libs build for other ABIs 2022-06-23 16:55:19 +02:00
Matéo Duparc 6cd6d9ef5d
Fix vendor libs build 2022-06-22 22:32:05 +02:00
Matéo Duparc 412df2e7be
Don't rebuild boost everytimes 2022-06-22 18:21:33 +02:00
Matéo Duparc e9f000353b
CMake libs build 2022-06-21 19:30:00 +02:00
Matéo Duparc 03fffc44a5 Revert "Ignore vendor_cryptopp"
This reverts commit 3866607d68.
2022-06-20 12:08:51 +02:00
Matéo Duparc 56c7d96bbf Volume creation 2022-06-19 17:56:34 +02:00
Matéo Duparc e6d735dbab Genesis 2022-06-18 21:11:24 +02:00
Matéo Duparc 3866607d68 Ignore vendor_cryptopp 2022-06-09 15:28:08 +02:00
Matéo Duparc 3df8023b21 Remove tests 2022-06-09 15:26:04 +02:00
29 changed files with 2389 additions and 277 deletions

View File

@ -42,8 +42,5 @@ if(MSVC)
add_definitions(/bigobj)
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(src)

View File

@ -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 )
* 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 )
* Updated to DokanY 1.3.0.1000
Version 0.11.2
---------------

View File

@ -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)
- 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
- Main program `cryfs-cli` removed
- 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)
- Logging output redirected to logcat
- JNI API created in `src/jni`

View File

@ -1,10 +0,0 @@
#pragma once
#ifndef CPPUTILS_SIZEDDATA_H
#define CPPUTILS_SIZEDDATA_H
struct SizedData {
unsigned char* data;
size_t size;
};
#endif

View File

@ -4,7 +4,6 @@
#include <thread>
#include <cpp-utils/macros.h>
#include <array>
#include <stdexcept>
namespace cpputils {

View File

@ -11,7 +11,6 @@
#include <cpp-utils/io/DontEchoStdinToStdoutRAII.h>
#include <cryfs/impl/filesystem/CryDevice.h>
#include <cryfs/impl/config/CryConfigLoader.h>
#include <cryfs/impl/config/CryDirectKeyProvider.h>
#include <cryfs/impl/config/CryPresetPasswordBasedKeyProvider.h>
#include <boost/filesystem.hpp>
@ -90,9 +89,9 @@ namespace cryfs_cli {
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 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()) {
switch(config.left()) {
case CryConfigFile::LoadError::DecryptionFailed:
@ -105,30 +104,24 @@ namespace cryfs_cli {
return std::move(config.right());
}
unique_ref<CryKeyProvider> Cli::_createKeyProvider(Credentials credentials) {
if (credentials.password == none) {
return make_unique_ref<CryDirectKeyProvider>(credentials.givenHash);
} else {
return make_unique_ref<CryPresetPasswordBasedKeyProvider>(
*credentials.password,
make_unique_ref<SCrypt>(_scryptSettings),
credentials.returnedHash
);
}
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) {
// TODO Instead of passing in _askPasswordXXX functions to KeyProvider, only pass in console and move logic to the key provider,
// for example by having a separate CryPasswordBasedKeyProvider / CryNoninteractivePasswordBasedKeyProvider.
auto keyProvider = make_unique_ref<CryPresetPasswordBasedKeyProvider>(
*password.get(),
make_unique_ref<SCrypt>(_scryptSettings)
);
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) {
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) {
fspp::fuse::Fuse* Cli::initFilesystem(const ProgramOptions &options, unique_ptr<string> password) {
cpputils::showBacktraceOnCrash();
cpputils::set_thread_name("cryfs");
try {
_sanityChecks(options);
LocalStateDir localStateDir(options.localStateDir());
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;
auto onIntegrityViolation = [&fuse] () {
@ -152,12 +145,14 @@ namespace cryfs_cli {
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();
return fuse;
} 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) {
LOG(ERR, "Crashed: {}", e.what());
} catch (...) {

View File

@ -5,13 +5,11 @@
#include <fspp/fuse/Fuse.h>
#include "program_options/ProgramOptions.h"
#include <cryfs/impl/config/CryConfigFile.h>
#include <cryfs/impl/config/CryKeyProvider.h>
#include <boost/filesystem/path.hpp>
#include <cpp-utils/tempfile/TempFile.h>
#include <cpp-utils/io/Console.h>
#include <cpp-utils/random/RandomGenerator.h>
#include <cpp-utils/network/HttpClient.h>
#include <cpp-utils/SizedData.h>
#include <cryfs/impl/filesystem/CryDevice.h>
#include "CallAfterTimeout.h"
#include <cryfs/impl/config/CryConfigLoader.h>
@ -20,20 +18,16 @@
namespace cryfs_cli {
class Cli final {
public:
struct Credentials {
boost::optional<string> password;
SizedData givenHash;
SizedData* returnedHash;
};
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:
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);
cpputils::unique_ref<cryfs::CryKeyProvider> _createKeyProvider(Credentials credentials);
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);
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);
boost::filesystem::path _determineConfigFile(const program_options::ProgramOptions &options);
void _initLogfile();
void _sanityChecks(const program_options::ProgramOptions &options);
void _checkDirAccessible(const boost::filesystem::path &dir, const std::string &name, bool createMissingDir, cryfs::ErrorCode errorCode);
void _sanityCheckFilesystem(cryfs::CryDevice *device);

View File

@ -19,7 +19,6 @@ set(LIB_SOURCES
impl/config/CryKeyProvider.cpp
impl/config/CryPasswordBasedKeyProvider.cpp
impl/config/CryPresetPasswordBasedKeyProvider.cpp
impl/config/CryDirectKeyProvider.cpp
impl/filesystem/CryOpenFile.cpp
impl/filesystem/fsblobstore/utils/DirEntry.cpp
impl/filesystem/fsblobstore/utils/DirEntryList.cpp

View File

@ -93,6 +93,8 @@ void CryConfigLoader::_checkMissingBlocksAreIntegrityViolations(CryConfigFile *c
auto exclusiveClientId = configFile->config()->ExclusiveClientId();
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);
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) {
auto config = _creator.create(_cipherFromCommandLine, _blocksizeBytesFromCommandLine, _missingBlockIsIntegrityViolationFromCommandLine, allowReplacedFilesystem);
auto result = CryConfigFile::create(std::move(filename), config.config, _keyProvider.get());

View File

@ -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> 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:
cpputils::either<CryConfigFile::LoadError, CryConfigLoader::ConfigLoadResult> _loadConfig(boost::filesystem::path filename, bool allowFilesystemUpgrade, bool allowReplacedFilesystem, CryConfigFile::Access access);

View File

@ -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");
}
}

View File

@ -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

View File

@ -8,26 +8,15 @@ using cpputils::Data;
namespace cryfs {
CryPresetPasswordBasedKeyProvider::CryPresetPasswordBasedKeyProvider(std::string password, unique_ref<PasswordBasedKDF> kdf, SizedData* returnedHash)
: _password(std::move(password)), _kdf(std::move(kdf)), _returnedHash(returnedHash) {}
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);
}
}
CryPresetPasswordBasedKeyProvider::CryPresetPasswordBasedKeyProvider(std::string password, unique_ref<PasswordBasedKDF> kdf)
: _password(std::move(password)), _kdf(std::move(kdf)) {}
EncryptionKey CryPresetPasswordBasedKeyProvider::requestKeyForExistingFilesystem(size_t keySize, const Data& kdfParameters) {
EncryptionKey encryptionKey = _kdf->deriveExistingKey(keySize, _password, kdfParameters);
saveEncryptionKey(encryptionKey);
return encryptionKey;
return _kdf->deriveExistingKey(keySize, _password, kdfParameters);
}
CryPresetPasswordBasedKeyProvider::KeyResult CryPresetPasswordBasedKeyProvider::requestKeyForNewFilesystem(size_t keySize) {
auto keyResult = _kdf->deriveNewKey(keySize, _password);
saveEncryptionKey(keyResult.key);
return {std::move(keyResult.key), std::move(keyResult.kdfParameters)};
}

View File

@ -5,27 +5,19 @@
#include "CryKeyProvider.h"
#include <functional>
#include <cpp-utils/crypto/kdf/PasswordBasedKDF.h>
#include <cpp-utils/SizedData.h>
namespace cryfs {
class CryPresetPasswordBasedKeyProvider final : public CryKeyProvider {
public:
explicit CryPresetPasswordBasedKeyProvider(
std::string password,
cpputils::unique_ref<cpputils::PasswordBasedKDF> kdf,
SizedData* returnedHash
);
explicit CryPresetPasswordBasedKeyProvider(std::string password, cpputils::unique_ref<cpputils::PasswordBasedKDF> kdf);
cpputils::EncryptionKey requestKeyForExistingFilesystem(size_t keySize, const cpputils::Data& kdfParameters) override;
KeyResult requestKeyForNewFilesystem(size_t keySize) override;
private:
void saveEncryptionKey(cpputils::EncryptionKey encryptionKey);
std::string _password;
cpputils::unique_ref<cpputils::PasswordBasedKDF> _kdf;
SizedData* _returnedHash;
DISALLOW_COPY_AND_ASSIGN(CryPresetPasswordBasedKeyProvider);
};

View File

@ -58,8 +58,16 @@ public:
// Remove the following line, if you don't want to output each fuse operation on the console
//#define FSPP_LOG 1
Fuse::Fuse(std::function<shared_ptr<Filesystem> ()> init)
:_init(std::move(init)), _fs(make_shared<InvalidFilesystem>()), _running(false) {
Fuse::~Fuse() {
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");
}
@ -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) {
ThreadNameForDebugging _threadName("mkdir");
#ifdef FSPP_LOG
LOG(DEBUG, "mkdir({}, {})", path.string(), mode);
LOG(DEBUG, "mkdir({}, {})", path, mode);
#endif
try {
ASSERT(is_valid_fspp_path(path), "has to be an absolute path");
// DokanY seems to call mkdir("/"). Ignore that
if ("/" == path) {
#ifdef FSPP_LOG
LOG(DEBUG, "mkdir({}, {}): ignored", path.string(), mode);
LOG(DEBUG, "mkdir({}, {}): ignored", path, mode);
#endif
return 0;
}
@ -344,7 +352,7 @@ int Fuse::rename(const bf::path &from, const bf::path &to) {
//TODO
int Fuse::link(const bf::path &from, const bf::path &to) {
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_to = _impl->RootDir() / to;
//int retstat = ::link(real_from.string().c_str(), real_to.string().c_str());

View File

@ -25,7 +25,8 @@ class Filesystem;
class Fuse final {
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;
void stop();
@ -70,7 +71,10 @@ private:
std::function<std::shared_ptr<Filesystem> ()> _init;
std::shared_ptr<Filesystem> _fs;
std::vector<char*> _argv;
std::atomic<bool> _running;
std::string _fstype;
boost::optional<std::string> _fsname;
boost::optional<Context> _context;
::uid_t uid;
::gid_t gid;

View File

@ -1,5 +1,8 @@
project (gitversion)
include(gitversion.cmake)
get_git_version(GIT_VERSION)
set(SOURCES
gitversion.cpp
versionstring.cpp
@ -9,9 +12,6 @@ set(SOURCES
add_library(${PROJECT_NAME} STATIC ${SOURCES})
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_add_boost(${PROJECT_NAME})
target_enable_style_warnings(${PROJECT_NAME})

View File

@ -0,0 +1,3 @@
include versioneer.py
include _version_source.py
include _version.py

487
src/gitversion/_version.py Normal file
View File

@ -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"}

5
src/gitversion/getversion.py Executable file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env python
import versioneer
print(versioneer.get_version())

View File

@ -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)

12
src/gitversion/setup.cfg Normal file
View File

@ -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-

13
src/gitversion/setup.py Normal file
View File

@ -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'
)

1778
src/gitversion/versioneer.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,10 @@
#include <jni.h>
jlong cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalSateDir, jbyteArray jpassword,
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_init(JNIEnv* env, jstring jbaseDir, jstring jlocalSateDir, jbyteArray jpassword, jboolean createBaseDir, jstring jcipher);
jlong cryfs_create(JNIEnv* env, jlong fusePtr, jstring jpath, mode_t mode);
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_write(JNIEnv* env, jlong fusePtr, jlong fileHandle, jlong fileOffset, jbyteArray buffer, jlong srcOffset, 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 offset, jbyteArray jbuffer, jint size);
jint cryfs_truncate(JNIEnv* env, jlong fusePtr, jstring jpath, jlong size);
jint cryfs_unlink(JNIEnv* env, jlong fusePtr, jstring jpath);
jint cryfs_release(jlong fusePtr, jlong fileHandle);

View File

@ -1,11 +1,9 @@
#include <jni.h>
#include <cryfs-cli/Cli.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 cpputils::Random;
using cpputils::SCrypt;
@ -15,21 +13,7 @@ using fspp::fuse::Fuse;
std::set<jlong> validFusePtrs;
jfieldID getValueField(JNIEnv* env, jobject object) {
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) {
extern "C" jlong cryfs_init(JNIEnv* env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpassword, jboolean createBaseDir, jstring jcipher) {
const char* baseDir = env->GetStringUTFChars(jbaseDir, NULL);
const char* localStateDir = env->GetStringUTFChars(jlocalStateDir, NULL);
boost::optional<string> cipher = none;
@ -38,44 +22,16 @@ cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpa
cipher = boost::optional<string>(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);
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(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);
if (fusePtr != 0) {
validFusePtrs.insert(fusePtr);
@ -83,55 +39,6 @@ cryfs_init(JNIEnv *env, jstring jbaseDir, jstring jlocalStateDir, jbyteArray jpa
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) {
Fuse* fuse = reinterpret_cast<Fuse*>(fusePtr);
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);
const jsize size = env->GetArrayLength(jbuffer);
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);
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);
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);
return result;

@ -1 +1 @@
Subproject commit c6012c576e30ff6000ddab0988d59bad849200ce
Subproject commit 0e12fbd30cb70b668a117c0913a303acfdaae04f

View File

@ -1146,7 +1146,7 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.1" AND USE_OPENMP)
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")
set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include")
set(OpenMP_CXX_LIB_NAMES omp)
@ -1154,23 +1154,9 @@ if (${CMAKE_VERSION} VERSION_GREATER "3.1" AND USE_OPENMP)
find_package(OpenMP)
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()
message(FATAL_ERROR "OpenMP: Didn't find libomp. Tried homebrew default location for Intel Macs 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.")
message(FATAL_ERROR "OpenMP: Didn't find libomp. Tried homebrew default location but also didn't find it.")
endif()
endif()

2
vendor/spdlog vendored

@ -1 +1 @@
Subproject commit 7e635fca68d014934b4af8a1cf874f63989352b7
Subproject commit a26e174b367a60a51f0be83a81d6d066330cdd8f