mirror of
https://github.com/vgough/encfs.git
synced 2024-11-24 17:03:13 +01:00
replace boost serialization with tinyxml2
This commit is contained in:
parent
bbf3d6f679
commit
e78d1659e3
@ -48,11 +48,8 @@ add_definitions (-D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26)
|
|||||||
find_package (OpenSSL REQUIRED)
|
find_package (OpenSSL REQUIRED)
|
||||||
include_directories (${OPENSSL_INCLUDE_DIR})
|
include_directories (${OPENSSL_INCLUDE_DIR})
|
||||||
|
|
||||||
find_package(Boost
|
find_package (TinyXML REQUIRED)
|
||||||
1.34.0
|
include_directories (${TINYXML_INCLUDE_DIR})
|
||||||
REQUIRED
|
|
||||||
COMPONENTS serialization)
|
|
||||||
include_directories (${Boost_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
find_package (RLog REQUIRED)
|
find_package (RLog REQUIRED)
|
||||||
add_definitions (-DRLOG_COMPONENT="encfs")
|
add_definitions (-DRLOG_COMPONENT="encfs")
|
||||||
@ -130,6 +127,7 @@ set(SOURCE_FILES
|
|||||||
encfs/readpassphrase.cpp
|
encfs/readpassphrase.cpp
|
||||||
encfs/SSL_Cipher.cpp
|
encfs/SSL_Cipher.cpp
|
||||||
encfs/StreamNameIO.cpp
|
encfs/StreamNameIO.cpp
|
||||||
|
encfs/XmlReader.cpp
|
||||||
)
|
)
|
||||||
add_library(encfs SHARED ${SOURCE_FILES})
|
add_library(encfs SHARED ${SOURCE_FILES})
|
||||||
set_property(TARGET encfs PROPERTY VERSION ${ENCFS_VERSION})
|
set_property(TARGET encfs PROPERTY VERSION ${ENCFS_VERSION})
|
||||||
@ -137,7 +135,7 @@ set_property(TARGET encfs PROPERTY SOVERSION ${ENCFS_SOVERSION})
|
|||||||
target_link_libraries(encfs
|
target_link_libraries(encfs
|
||||||
${FUSE_LIBRARIES}
|
${FUSE_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
${Boost_LIBRARIES}
|
${TINYXML_LIBRARIES}
|
||||||
${RLOG_LIBRARIES}
|
${RLOG_LIBRARIES}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,7 @@ Dependencies
|
|||||||
|
|
||||||
EncFS depends on a number of libraries:
|
EncFS depends on a number of libraries:
|
||||||
|
|
||||||
openssl fuse boost-serialization gettext libintl librlog
|
openssl fuse tinyxml2 gettext libintl librlog
|
||||||
|
|
||||||
Compiling on Debian and Ubuntu
|
Compiling on Debian and Ubuntu
|
||||||
==============================
|
==============================
|
||||||
|
@ -4,8 +4,7 @@ machine:
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
pre:
|
pre:
|
||||||
- sudo apt-get update
|
- sudo apt-get install cmake libfuse-dev librlog-dev libgettextpo-dev libtinyxml2-dev
|
||||||
- sudo apt-get install cmake libfuse-dev librlog-dev libgettextpo-dev
|
|
||||||
- bash ./ci/install-gcc.sh
|
- bash ./ci/install-gcc.sh
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
26
cmake/FindTinyXML.cmake
Normal file
26
cmake/FindTinyXML.cmake
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# - Find TinyXML
|
||||||
|
# Find the native TinyXML includes and library
|
||||||
|
#
|
||||||
|
# TINYXML_FOUND - True if TinyXML found.
|
||||||
|
# TINYXML_INCLUDE_DIR - where to find tinyxml.h, etc.
|
||||||
|
# TINYXML_LIBRARIES - List of libraries when using TinyXML.
|
||||||
|
#
|
||||||
|
|
||||||
|
IF( TINYXML_INCLUDE_DIR )
|
||||||
|
# Already in cache, be silent
|
||||||
|
SET( TinyXML_FIND_QUIETLY TRUE )
|
||||||
|
ENDIF( TINYXML_INCLUDE_DIR )
|
||||||
|
|
||||||
|
FIND_PATH( TINYXML_INCLUDE_DIR "tinyxml2.h"
|
||||||
|
PATH_SUFFIXES "tinyxml2" )
|
||||||
|
|
||||||
|
FIND_LIBRARY( TINYXML_LIBRARIES
|
||||||
|
NAMES "tinyxml2"
|
||||||
|
PATH_SUFFIXES "tinyxml2" )
|
||||||
|
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set TINYXML_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
INCLUDE( "FindPackageHandleStandardArgs" )
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS( "TinyXML" DEFAULT_MSG TINYXML_INCLUDE_DIR TINYXML_LIBRARIES )
|
||||||
|
|
||||||
|
MARK_AS_ADVANCED( TINYXML_INCLUDE_DIR TINYXML_LIBRARIES )
|
2
devmode
Normal file → Executable file
2
devmode
Normal file → Executable file
@ -1,4 +1,4 @@
|
|||||||
# Script which sets up the CMake build for Debug mode.
|
# Script which sets up the CMake build for Debug mode.
|
||||||
# After running, chdir to the build subdir ane run "make"
|
# After running, chdir to the build subdir ane run "make"
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug $@
|
cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fsanitize=address" $@
|
||||||
|
@ -4,7 +4,7 @@ FROM ubuntu
|
|||||||
# Do system updates and install dependencies
|
# Do system updates and install dependencies
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get -y upgrade
|
RUN apt-get -y upgrade
|
||||||
RUN sudo apt-get -y install git wget autopoint libfuse-dev libboost-serialization-dev
|
RUN sudo apt-get -y install git wget autopoint libfuse-dev libtinyxml2-dev
|
||||||
RUN apt-get clean
|
RUN apt-get clean
|
||||||
|
|
||||||
# Download Drone.io
|
# Download Drone.io
|
||||||
|
@ -31,10 +31,10 @@ RUN apt-get -y upgrade \
|
|||||||
&& apt-get -y install \
|
&& apt-get -y install \
|
||||||
git \
|
git \
|
||||||
libfuse-dev \
|
libfuse-dev \
|
||||||
libboost-serialization-dev \
|
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
librlog-dev \
|
librlog-dev \
|
||||||
gettext \
|
gettext \
|
||||||
libgettextpo-dev \
|
libgettextpo-dev \
|
||||||
|
libtinyxml2-dev \
|
||||||
&& apt-get clean
|
&& apt-get clean
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#ifndef _FSConfig_incl_
|
#ifndef _FSConfig_incl_
|
||||||
#define _FSConfig_incl_
|
#define _FSConfig_incl_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "encfs.h"
|
#include "encfs.h"
|
||||||
@ -54,12 +55,13 @@ struct EncFSConfig {
|
|||||||
rel::Interface cipherIface;
|
rel::Interface cipherIface;
|
||||||
// interface used for file name coding
|
// interface used for file name coding
|
||||||
rel::Interface nameIface;
|
rel::Interface nameIface;
|
||||||
|
|
||||||
int keySize; // reported in bits
|
int keySize; // reported in bits
|
||||||
int blockSize; // reported in bytes
|
int blockSize; // reported in bytes
|
||||||
|
|
||||||
std::vector<unsigned char> keyData;
|
std::vector<unsigned char> keyData;
|
||||||
|
|
||||||
std::vector<unsigned char> salt;
|
std::vector<unsigned char> salt;
|
||||||
|
|
||||||
int kdfIterations;
|
int kdfIterations;
|
||||||
long desiredKDFDuration;
|
long desiredKDFDuration;
|
||||||
|
|
||||||
|
@ -24,12 +24,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#define _BSD_SOURCE // pick up setenv on RH7.3
|
#define _BSD_SOURCE // pick up setenv on RH7.3
|
||||||
|
|
||||||
#include <boost/version.hpp>
|
|
||||||
#include <boost/archive/xml_iarchive.hpp>
|
|
||||||
#include <boost/archive/xml_oarchive.hpp>
|
|
||||||
#include <boost/serialization/binary_object.hpp>
|
|
||||||
#include <boost/serialization/nvp.hpp>
|
|
||||||
#include <boost/serialization/split_free.hpp>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <rlog/Error.h>
|
#include <rlog/Error.h>
|
||||||
#include <rlog/rlog.h>
|
#include <rlog/rlog.h>
|
||||||
@ -45,6 +39,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <tinyxml2.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "BlockNameIO.h"
|
#include "BlockNameIO.h"
|
||||||
@ -59,7 +54,9 @@
|
|||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
#include "NameIO.h"
|
#include "NameIO.h"
|
||||||
#include "Range.h"
|
#include "Range.h"
|
||||||
|
#include "XmlReader.h"
|
||||||
#include "autosprintf.h"
|
#include "autosprintf.h"
|
||||||
|
#include "base64.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include "intl/gettext.h"
|
#include "intl/gettext.h"
|
||||||
@ -73,7 +70,6 @@ using namespace rel;
|
|||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using gnu::autosprintf;
|
using gnu::autosprintf;
|
||||||
namespace serial = boost::serialization;
|
|
||||||
|
|
||||||
static const int DefaultBlockSize = 1024;
|
static const int DefaultBlockSize = 1024;
|
||||||
// The maximum length of text passwords. If longer are needed,
|
// The maximum length of text passwords. If longer are needed,
|
||||||
@ -108,9 +104,8 @@ struct ConfigInfo {
|
|||||||
const char *fileName;
|
const char *fileName;
|
||||||
ConfigType type;
|
ConfigType type;
|
||||||
const char *environmentOverride;
|
const char *environmentOverride;
|
||||||
bool (*loadFunc)(const char *fileName, const shared_ptr<EncFSConfig> &config,
|
bool (*loadFunc)(const char *fileName, EncFSConfig *config, ConfigInfo *cfg);
|
||||||
ConfigInfo *cfg);
|
bool (*saveFunc)(const char *fileName, const EncFSConfig *config);
|
||||||
bool (*saveFunc)(const char *fileName, const shared_ptr<EncFSConfig> &config);
|
|
||||||
int currentSubVersion;
|
int currentSubVersion;
|
||||||
int defaultSubVersion;
|
int defaultSubVersion;
|
||||||
} ConfigFileMapping[] = {
|
} ConfigFileMapping[] = {
|
||||||
@ -127,121 +122,6 @@ struct ConfigInfo {
|
|||||||
{".encfs", Config_Prehistoric, NULL, NULL, NULL, 0, 0},
|
{".encfs", Config_Prehistoric, NULL, NULL, NULL, 0, 0},
|
||||||
{NULL, Config_None, NULL, NULL, NULL, 0, 0}};
|
{NULL, Config_None, NULL, NULL, NULL, 0, 0}};
|
||||||
|
|
||||||
#include "boost-versioning.h" // IWYU pragma: keep
|
|
||||||
|
|
||||||
// define serialization helpers
|
|
||||||
namespace boost {
|
|
||||||
namespace serialization {
|
|
||||||
template <class Archive>
|
|
||||||
void save(Archive &ar, const EncFSConfig &cfg, unsigned int version) {
|
|
||||||
(void)version;
|
|
||||||
// version 20 (aka 20100613)
|
|
||||||
if (cfg.subVersion == 0)
|
|
||||||
ar << make_nvp("version", V6SubVersion);
|
|
||||||
else
|
|
||||||
ar << make_nvp("version", cfg.subVersion);
|
|
||||||
|
|
||||||
ar << make_nvp("creator", cfg.creator);
|
|
||||||
ar << make_nvp("cipherAlg", cfg.cipherIface);
|
|
||||||
ar << make_nvp("nameAlg", cfg.nameIface);
|
|
||||||
ar << make_nvp("keySize", cfg.keySize);
|
|
||||||
ar << make_nvp("blockSize", cfg.blockSize);
|
|
||||||
ar << make_nvp("uniqueIV", cfg.uniqueIV);
|
|
||||||
ar << make_nvp("chainedNameIV", cfg.chainedNameIV);
|
|
||||||
ar << make_nvp("externalIVChaining", cfg.externalIVChaining);
|
|
||||||
ar << make_nvp("blockMACBytes", cfg.blockMACBytes);
|
|
||||||
ar << make_nvp("blockMACRandBytes", cfg.blockMACRandBytes);
|
|
||||||
ar << make_nvp("allowHoles", cfg.allowHoles);
|
|
||||||
|
|
||||||
int encodedSize = cfg.keyData.size();
|
|
||||||
ar << make_nvp("encodedKeySize", encodedSize);
|
|
||||||
ar << make_nvp("encodedKeyData",
|
|
||||||
serial::make_binary_object(cfg.getKeyData(), encodedSize));
|
|
||||||
|
|
||||||
// version 20080816
|
|
||||||
int size = cfg.salt.size();
|
|
||||||
ar << make_nvp("saltLen", size);
|
|
||||||
ar << make_nvp("saltData",
|
|
||||||
serial::make_binary_object(cfg.getSaltData(), size));
|
|
||||||
ar << make_nvp("kdfIterations", cfg.kdfIterations);
|
|
||||||
ar << make_nvp("desiredKDFDuration", cfg.desiredKDFDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void load(Archive &ar, EncFSConfig &cfg, unsigned int version) {
|
|
||||||
rInfo("version = %i", version);
|
|
||||||
// TODO: figure out how to deprecate all but the first case..
|
|
||||||
if (version == 20 || version >= 20100713) {
|
|
||||||
rInfo("found new serialization format");
|
|
||||||
ar >> make_nvp("version", cfg.subVersion);
|
|
||||||
} else if (version == 26800) {
|
|
||||||
rInfo("found 20080816 version");
|
|
||||||
cfg.subVersion = 20080816;
|
|
||||||
} else if (version == 26797) {
|
|
||||||
rInfo("found 20080813");
|
|
||||||
cfg.subVersion = 20080813;
|
|
||||||
} else if (version < (unsigned int)V5SubVersion) {
|
|
||||||
rError("Invalid version %i - please fix config file", version);
|
|
||||||
} else {
|
|
||||||
rInfo("Boost <= 1.41 compatibility mode");
|
|
||||||
cfg.subVersion = version;
|
|
||||||
}
|
|
||||||
rInfo("subVersion = %i", cfg.subVersion);
|
|
||||||
|
|
||||||
ar >> make_nvp("creator", cfg.creator);
|
|
||||||
ar >> make_nvp("cipherAlg", cfg.cipherIface);
|
|
||||||
ar >> make_nvp("nameAlg", cfg.nameIface);
|
|
||||||
ar >> make_nvp("keySize", cfg.keySize);
|
|
||||||
ar >> make_nvp("blockSize", cfg.blockSize);
|
|
||||||
ar >> make_nvp("uniqueIV", cfg.uniqueIV);
|
|
||||||
ar >> make_nvp("chainedNameIV", cfg.chainedNameIV);
|
|
||||||
ar >> make_nvp("externalIVChaining", cfg.externalIVChaining);
|
|
||||||
ar >> make_nvp("blockMACBytes", cfg.blockMACBytes);
|
|
||||||
ar >> make_nvp("blockMACRandBytes", cfg.blockMACRandBytes);
|
|
||||||
ar >> make_nvp("allowHoles", cfg.allowHoles);
|
|
||||||
|
|
||||||
int encodedSize;
|
|
||||||
ar >> make_nvp("encodedKeySize", encodedSize);
|
|
||||||
rAssert(encodedSize == cfg.getCipher()->encodedKeySize());
|
|
||||||
|
|
||||||
unsigned char *key = new unsigned char[encodedSize];
|
|
||||||
ar >>
|
|
||||||
make_nvp("encodedKeyData", serial::make_binary_object(key, encodedSize));
|
|
||||||
cfg.assignKeyData(key, encodedSize);
|
|
||||||
delete[] key;
|
|
||||||
|
|
||||||
if (cfg.subVersion >= 20080816) {
|
|
||||||
int saltLen;
|
|
||||||
ar >> make_nvp("saltLen", saltLen);
|
|
||||||
unsigned char *salt = new unsigned char[saltLen];
|
|
||||||
ar >> make_nvp("saltData", serial::make_binary_object(salt, saltLen));
|
|
||||||
cfg.assignSaltData(salt, saltLen);
|
|
||||||
delete[] salt;
|
|
||||||
|
|
||||||
ar >> make_nvp("kdfIterations", cfg.kdfIterations);
|
|
||||||
ar >> make_nvp("desiredKDFDuration", cfg.desiredKDFDuration);
|
|
||||||
} else {
|
|
||||||
cfg.salt.clear();
|
|
||||||
cfg.kdfIterations = 16;
|
|
||||||
cfg.desiredKDFDuration = NormalKDFDuration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void serialize(Archive &ar, EncFSConfig &cfg, unsigned int version) {
|
|
||||||
split_free(ar, cfg, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
void serialize(Archive &ar, Interface &i, const unsigned int version) {
|
|
||||||
(void)version;
|
|
||||||
ar &make_nvp("name", i.name());
|
|
||||||
ar &make_nvp("major", i.current());
|
|
||||||
ar &make_nvp("minor", i.revision());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EncFS_Root::EncFS_Root() {}
|
EncFS_Root::EncFS_Root() {}
|
||||||
|
|
||||||
EncFS_Root::~EncFS_Root() {}
|
EncFS_Root::~EncFS_Root() {}
|
||||||
@ -330,7 +210,7 @@ bool userAllowMkdir(int promptno, const char *path, mode_t mode) {
|
|||||||
* Load config file by calling the load function on the filename
|
* Load config file by calling the load function on the filename
|
||||||
*/
|
*/
|
||||||
ConfigType readConfig_load(ConfigInfo *nm, const char *path,
|
ConfigType readConfig_load(ConfigInfo *nm, const char *path,
|
||||||
const shared_ptr<EncFSConfig> &config) {
|
EncFSConfig *config) {
|
||||||
if (nm->loadFunc) {
|
if (nm->loadFunc) {
|
||||||
try {
|
try {
|
||||||
if ((*nm->loadFunc)(path, config, nm)) {
|
if ((*nm->loadFunc)(path, config, nm)) {
|
||||||
@ -354,8 +234,7 @@ ConfigType readConfig_load(ConfigInfo *nm, const char *path,
|
|||||||
* Try to locate the config file
|
* Try to locate the config file
|
||||||
* Tries the most recent format first, then looks for older versions
|
* Tries the most recent format first, then looks for older versions
|
||||||
*/
|
*/
|
||||||
ConfigType readConfig(const string &rootDir,
|
ConfigType readConfig(const string &rootDir, EncFSConfig *config) {
|
||||||
const shared_ptr<EncFSConfig> &config) {
|
|
||||||
ConfigInfo *nm = ConfigFileMapping;
|
ConfigInfo *nm = ConfigFileMapping;
|
||||||
while (nm->fileName) {
|
while (nm->fileName) {
|
||||||
// allow environment variable to override default config path
|
// allow environment variable to override default config path
|
||||||
@ -386,32 +265,96 @@ ConfigType readConfig(const string &rootDir,
|
|||||||
* Read config file in current "V6" XML format, normally named ".encfs6.xml"
|
* Read config file in current "V6" XML format, normally named ".encfs6.xml"
|
||||||
* This format is in use since Apr 13, 2008 (commit 6d081f5c)
|
* This format is in use since Apr 13, 2008 (commit 6d081f5c)
|
||||||
*/
|
*/
|
||||||
bool readV6Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
// Read a boost::serialization config file using an Xml reader..
|
||||||
|
bool readV6Config(const char *configFile, EncFSConfig *cfg,
|
||||||
ConfigInfo *info) {
|
ConfigInfo *info) {
|
||||||
(void)info;
|
(void)info;
|
||||||
|
|
||||||
ifstream st(configFile);
|
XmlReader rdr;
|
||||||
if (st.is_open()) {
|
if (!rdr.load(configFile)) {
|
||||||
try {
|
rError("Failed to load config file %s", configFile);
|
||||||
boost::archive::xml_iarchive ia(st);
|
|
||||||
ia >> BOOST_SERIALIZATION_NVP(*config);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (boost::archive::archive_exception &e) {
|
|
||||||
rError("Archive exception: %s", e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rInfo("Failed to load config file %s", configFile);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XmlValuePtr serialization = rdr["boost_serialization"];
|
||||||
|
XmlValuePtr config = (*serialization)["cfg"];
|
||||||
|
if (!config) {
|
||||||
|
config = (*serialization)["config"];
|
||||||
|
}
|
||||||
|
if (!config) {
|
||||||
|
rError("Unable to find XML configuration in file %s", configFile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int version;
|
||||||
|
if (!config->read("version", &version) &&
|
||||||
|
!config->read("@version", &version)) {
|
||||||
|
rError("Unable to find version in config file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// version numbering was complicated by boost::archive
|
||||||
|
if (version == 20 || version >= 20100713) {
|
||||||
|
rDebug("found new serialization format");
|
||||||
|
cfg->subVersion = version;
|
||||||
|
} else if (version == 26800) {
|
||||||
|
rDebug("found 20080816 version");
|
||||||
|
cfg->subVersion = 20080816;
|
||||||
|
} else if (version == 26797) {
|
||||||
|
rDebug("found 20080813");
|
||||||
|
cfg->subVersion = 20080813;
|
||||||
|
} else if (version < V5SubVersion) {
|
||||||
|
rError("Invalid version %d - please fix config file", version);
|
||||||
|
} else {
|
||||||
|
rInfo("Boost <= 1.41 compatibility mode");
|
||||||
|
cfg->subVersion = version;
|
||||||
|
}
|
||||||
|
rDebug("subVersion = %d", cfg->subVersion);
|
||||||
|
|
||||||
|
config->read("creator", &cfg->creator);
|
||||||
|
config->read("cipherAlg", &cfg->cipherIface);
|
||||||
|
config->read("nameAlg", &cfg->nameIface);
|
||||||
|
|
||||||
|
config->read("keySize", &cfg->keySize);
|
||||||
|
|
||||||
|
config->read("blockSize", &cfg->blockSize);
|
||||||
|
config->read("uniqueIV", &cfg->uniqueIV);
|
||||||
|
config->read("chainedNameIV", &cfg->chainedNameIV);
|
||||||
|
config->read("externalIVChaining", &cfg->externalIVChaining);
|
||||||
|
config->read("blockMACBytes", &cfg->blockMACBytes);
|
||||||
|
config->read("blockMACRandBytes", &cfg->blockMACRandBytes);
|
||||||
|
config->read("allowHoles", &cfg->allowHoles);
|
||||||
|
|
||||||
|
int encodedSize;
|
||||||
|
config->read("encodedKeySize", &encodedSize);
|
||||||
|
unsigned char *key = new unsigned char[encodedSize];
|
||||||
|
config->readB64("encodedKeyData", key, encodedSize);
|
||||||
|
cfg->assignKeyData(key, encodedSize);
|
||||||
|
delete[] key;
|
||||||
|
|
||||||
|
if (cfg->subVersion >= 20080816) {
|
||||||
|
int saltLen;
|
||||||
|
config->read("saltLen", &saltLen);
|
||||||
|
unsigned char *salt = new unsigned char[saltLen];
|
||||||
|
config->readB64("saltData", salt, saltLen);
|
||||||
|
cfg->assignSaltData(salt, saltLen);
|
||||||
|
delete[] salt;
|
||||||
|
|
||||||
|
config->read("kdfIterations", &cfg->kdfIterations);
|
||||||
|
config->read("desiredKDFDuration", &cfg->desiredKDFDuration);
|
||||||
|
} else {
|
||||||
|
cfg->kdfIterations = 16;
|
||||||
|
cfg->desiredKDFDuration = NormalKDFDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read config file in deprecated "V5" format, normally named ".encfs5"
|
* Read config file in deprecated "V5" format, normally named ".encfs5"
|
||||||
* This format has been used before Apr 13, 2008
|
* This format has been used before Apr 13, 2008
|
||||||
*/
|
*/
|
||||||
bool readV5Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
bool readV5Config(const char *configFile, EncFSConfig *config,
|
||||||
ConfigInfo *info) {
|
ConfigInfo *info) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
@ -466,7 +409,7 @@ bool readV5Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
|||||||
* Read config file in deprecated "V4" format, normally named ".encfs4"
|
* Read config file in deprecated "V4" format, normally named ".encfs4"
|
||||||
* This format has been used before Jan 7, 2008
|
* This format has been used before Jan 7, 2008
|
||||||
*/
|
*/
|
||||||
bool readV4Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
bool readV4Config(const char *configFile, EncFSConfig *config,
|
||||||
ConfigInfo *info) {
|
ConfigInfo *info) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
@ -503,7 +446,7 @@ bool readV4Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool saveConfig(ConfigType type, const string &rootDir,
|
bool saveConfig(ConfigType type, const string &rootDir,
|
||||||
const shared_ptr<EncFSConfig> &config) {
|
const EncFSConfig *config) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
ConfigInfo *nm = ConfigFileMapping;
|
ConfigInfo *nm = ConfigFileMapping;
|
||||||
@ -530,31 +473,93 @@ bool saveConfig(ConfigType type, const string &rootDir,
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool writeV6Config(const char *configFile,
|
template <typename T>
|
||||||
const shared_ptr<EncFSConfig> &config) {
|
tinyxml2::XMLElement *addEl(tinyxml2::XMLDocument &doc,
|
||||||
ofstream st(configFile);
|
tinyxml2::XMLNode *parent, const char *name,
|
||||||
if (!st.is_open()) return false;
|
T value) {
|
||||||
|
auto el = doc.NewElement(name);
|
||||||
st << *config;
|
el->SetText(value);
|
||||||
return true;
|
parent->InsertEndChild(el);
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &st, const EncFSConfig &cfg) {
|
template <>
|
||||||
boost::archive::xml_oarchive oa(st);
|
tinyxml2::XMLElement *addEl<>(tinyxml2::XMLDocument &doc,
|
||||||
oa << BOOST_SERIALIZATION_NVP(cfg);
|
tinyxml2::XMLNode *parent, const char *name,
|
||||||
|
Interface iface) {
|
||||||
|
auto el = doc.NewElement(name);
|
||||||
|
|
||||||
return st;
|
auto n = doc.NewElement("name");
|
||||||
|
n->SetText(iface.name().c_str());
|
||||||
|
el->InsertEndChild(n);
|
||||||
|
|
||||||
|
auto major = doc.NewElement("major");
|
||||||
|
major->SetText(iface.current());
|
||||||
|
el->InsertEndChild(major);
|
||||||
|
|
||||||
|
auto minor = doc.NewElement("minor");
|
||||||
|
minor->SetText(iface.revision());
|
||||||
|
el->InsertEndChild(minor);
|
||||||
|
|
||||||
|
parent->InsertEndChild(el);
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::istream &operator>>(std::istream &st, EncFSConfig &cfg) {
|
template <>
|
||||||
boost::archive::xml_iarchive ia(st);
|
tinyxml2::XMLElement *addEl<>(tinyxml2::XMLDocument &doc,
|
||||||
ia >> BOOST_SERIALIZATION_NVP(cfg);
|
tinyxml2::XMLNode *parent, const char *name,
|
||||||
|
std::vector<unsigned char> data) {
|
||||||
|
string v = string("\n") + B64StandardEncode(data) + "\n";
|
||||||
|
return addEl(doc, parent, name, v.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return st;
|
bool writeV6Config(const char *configFile, const EncFSConfig *cfg) {
|
||||||
|
tinyxml2::XMLDocument doc;
|
||||||
|
|
||||||
|
// Various static tags are included to make the output compatible with
|
||||||
|
// older boost-based readers.
|
||||||
|
doc.InsertEndChild(doc.NewDeclaration(nullptr));
|
||||||
|
doc.InsertEndChild(doc.NewUnknown("DOCTYPE boost_serialization"));
|
||||||
|
|
||||||
|
auto header = doc.NewElement("boost_serialization");
|
||||||
|
header->SetAttribute("signature", "serialization::archive");
|
||||||
|
header->SetAttribute("version", "7");
|
||||||
|
doc.InsertEndChild(header);
|
||||||
|
|
||||||
|
auto config = doc.NewElement("cfg");
|
||||||
|
config->SetAttribute("class_id", "0");
|
||||||
|
config->SetAttribute("tracking_level", "0");
|
||||||
|
config->SetAttribute("version", "20");
|
||||||
|
header->InsertEndChild(config);
|
||||||
|
|
||||||
|
addEl(doc, config, "version", V6SubVersion);
|
||||||
|
addEl(doc, config, "creator", cfg->creator.c_str());
|
||||||
|
auto cipherAlg = addEl(doc, config, "cipherAlg", cfg->cipherIface);
|
||||||
|
cipherAlg->SetAttribute("class_id", "1");
|
||||||
|
cipherAlg->SetAttribute("tracking_level", "0");
|
||||||
|
cipherAlg->SetAttribute("version", "0");
|
||||||
|
addEl(doc, config, "nameAlg", cfg->nameIface);
|
||||||
|
addEl(doc, config, "keySize", cfg->keySize);
|
||||||
|
addEl(doc, config, "blockSize", cfg->blockSize);
|
||||||
|
addEl(doc, config, "uniqueIV", cfg->uniqueIV);
|
||||||
|
addEl(doc, config, "chainedNameIV", cfg->chainedNameIV);
|
||||||
|
addEl(doc, config, "externalIVChaining", cfg->externalIVChaining);
|
||||||
|
addEl(doc, config, "blockMACBytes", cfg->blockMACBytes);
|
||||||
|
addEl(doc, config, "blockMACRandBytes", cfg->blockMACRandBytes);
|
||||||
|
addEl(doc, config, "allowHoles", cfg->allowHoles);
|
||||||
|
addEl(doc, config, "encodedKeySize", (int)cfg->keyData.size());
|
||||||
|
addEl(doc, config, "encodedKeyData", cfg->keyData);
|
||||||
|
addEl(doc, config, "saltLen", (int)cfg->salt.size());
|
||||||
|
addEl(doc, config, "saltData", cfg->salt);
|
||||||
|
addEl(doc, config, "kdfIterations", cfg->kdfIterations);
|
||||||
|
addEl(doc, config, "desiredKDFDuration", (int)cfg->desiredKDFDuration);
|
||||||
|
|
||||||
|
auto err = doc.SaveFile(configFile, false);
|
||||||
|
return err == tinyxml2::XML_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool writeV5Config(const char *configFile,
|
bool writeV5Config(const char *configFile,
|
||||||
const shared_ptr<EncFSConfig> &config) {
|
const EncFSConfig *config) {
|
||||||
ConfigReader cfg;
|
ConfigReader cfg;
|
||||||
|
|
||||||
cfg["creator"] << config->creator;
|
cfg["creator"] << config->creator;
|
||||||
@ -576,7 +581,7 @@ bool writeV5Config(const char *configFile,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool writeV4Config(const char *configFile,
|
bool writeV4Config(const char *configFile,
|
||||||
const shared_ptr<EncFSConfig> &config) {
|
const EncFSConfig *config) {
|
||||||
ConfigReader cfg;
|
ConfigReader cfg;
|
||||||
|
|
||||||
cfg["cipher"] << config->cipherIface;
|
cfg["cipher"] << config->cipherIface;
|
||||||
@ -1125,7 +1130,7 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
// xgroup(setup)
|
// xgroup(setup)
|
||||||
cout << _("Configuration finished. The filesystem to be created has\n"
|
cout << _("Configuration finished. The filesystem to be created has\n"
|
||||||
"the following properties:") << endl;
|
"the following properties:") << endl;
|
||||||
showFSInfo(config);
|
showFSInfo(config.get());
|
||||||
|
|
||||||
if (config->externalIVChaining) {
|
if (config->externalIVChaining) {
|
||||||
cout << _("-------------------------- WARNING --------------------------\n")
|
cout << _("-------------------------- WARNING --------------------------\n")
|
||||||
@ -1175,7 +1180,7 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
return rootInfo;
|
return rootInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!saveConfig(Config_V6, rootDir, config)) return rootInfo;
|
if (!saveConfig(Config_V6, rootDir, config.get())) return rootInfo;
|
||||||
|
|
||||||
// fill in config struct
|
// fill in config struct
|
||||||
shared_ptr<NameIO> nameCoder =
|
shared_ptr<NameIO> nameCoder =
|
||||||
@ -1208,7 +1213,7 @@ RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
return rootInfo;
|
return rootInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showFSInfo(const shared_ptr<EncFSConfig> &config) {
|
void showFSInfo(const EncFSConfig *config) {
|
||||||
shared_ptr<Cipher> cipher = Cipher::New(config->cipherIface, -1);
|
shared_ptr<Cipher> cipher = Cipher::New(config->cipherIface, -1);
|
||||||
{
|
{
|
||||||
cout << autosprintf(
|
cout << autosprintf(
|
||||||
@ -1517,7 +1522,7 @@ RootPtr initFS(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts) {
|
|||||||
RootPtr rootInfo;
|
RootPtr rootInfo;
|
||||||
shared_ptr<EncFSConfig> config(new EncFSConfig);
|
shared_ptr<EncFSConfig> config(new EncFSConfig);
|
||||||
|
|
||||||
if (readConfig(opts->rootDir, config) != Config_None) {
|
if (readConfig(opts->rootDir, config.get()) != Config_None) {
|
||||||
if (config->blockMACBytes == 0 && opts->requireMac) {
|
if (config->blockMACBytes == 0 && opts->requireMac) {
|
||||||
cout << _(
|
cout << _(
|
||||||
"The configuration disabled MAC, but you passed --require-macs\n");
|
"The configuration disabled MAC, but you passed --require-macs\n");
|
||||||
|
@ -69,11 +69,11 @@ enum ConfigMode { Config_Prompt, Config_Standard, Config_Paranoia };
|
|||||||
*/
|
*/
|
||||||
struct EncFS_Opts {
|
struct EncFS_Opts {
|
||||||
std::string rootDir;
|
std::string rootDir;
|
||||||
std::string mountPoint; // where to make filesystem visible
|
std::string mountPoint; // where to make filesystem visible
|
||||||
bool createIfNotFound; // create filesystem if not found
|
bool createIfNotFound; // create filesystem if not found
|
||||||
bool idleTracking; // turn on idle monitoring of filesystem
|
bool idleTracking; // turn on idle monitoring of filesystem
|
||||||
bool mountOnDemand; // mounting on-demand
|
bool mountOnDemand; // mounting on-demand
|
||||||
bool delayMount; // delay initial mount
|
bool delayMount; // delay initial mount
|
||||||
|
|
||||||
bool checkKey; // check crypto key decoding
|
bool checkKey; // check crypto key decoding
|
||||||
bool forceDecode; // force decode on MAC block failures
|
bool forceDecode; // force decode on MAC block failures
|
||||||
@ -118,15 +118,14 @@ struct EncFS_Opts {
|
|||||||
/*
|
/*
|
||||||
Read existing config file. Looks for any supported configuration version.
|
Read existing config file. Looks for any supported configuration version.
|
||||||
*/
|
*/
|
||||||
ConfigType readConfig(const std::string &rootDir,
|
ConfigType readConfig(const std::string &rootDir, EncFSConfig *config);
|
||||||
const shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Save the configuration. Saves back as the same configuration type as was
|
Save the configuration. Saves back as the same configuration type as was
|
||||||
read from.
|
read from.
|
||||||
*/
|
*/
|
||||||
bool saveConfig(ConfigType type, const std::string &rootdir,
|
bool saveConfig(ConfigType type, const std::string &rootdir,
|
||||||
const shared_ptr<EncFSConfig> &config);
|
const EncFSConfig *config);
|
||||||
|
|
||||||
class EncFS_Context;
|
class EncFS_Context;
|
||||||
|
|
||||||
@ -134,21 +133,18 @@ RootPtr initFS(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts);
|
|||||||
|
|
||||||
RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts);
|
RootPtr createV6Config(EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts);
|
||||||
|
|
||||||
void showFSInfo(const shared_ptr<EncFSConfig> &config);
|
void showFSInfo(const EncFSConfig *config);
|
||||||
|
|
||||||
bool readV4Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
bool readV4Config(const char *configFile, EncFSConfig *config,
|
||||||
struct ConfigInfo *);
|
struct ConfigInfo *);
|
||||||
bool writeV4Config(const char *configFile,
|
bool writeV4Config(const char *configFile, const EncFSConfig *config);
|
||||||
const shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
bool readV5Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
bool readV5Config(const char *configFile, EncFSConfig *config,
|
||||||
struct ConfigInfo *);
|
struct ConfigInfo *);
|
||||||
bool writeV5Config(const char *configFile,
|
bool writeV5Config(const char *configFile, const EncFSConfig *config);
|
||||||
const shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
bool readV6Config(const char *configFile, const shared_ptr<EncFSConfig> &config,
|
bool readV6Config(const char *configFile, EncFSConfig *config,
|
||||||
struct ConfigInfo *);
|
struct ConfigInfo *);
|
||||||
bool writeV6Config(const char *configFile,
|
bool writeV6Config(const char *configFile, const EncFSConfig *config);
|
||||||
const shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
192
encfs/XmlReader.cpp
Normal file
192
encfs/XmlReader.cpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Author: Valient Gough <vgough@pobox.com>
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (c) 2012-2013, Valient Gough
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "XmlReader.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
|
#include <rlog/Error.h>
|
||||||
|
#include <rlog/rlog.h>
|
||||||
|
|
||||||
|
#include "base64.h"
|
||||||
|
#include "Interface.h"
|
||||||
|
#include "shared_ptr.h"
|
||||||
|
|
||||||
|
XmlValue::~XmlValue() {}
|
||||||
|
|
||||||
|
XmlValuePtr XmlValue::operator[](const char *path) const { return find(path); }
|
||||||
|
|
||||||
|
XmlValuePtr XmlValue::find(const char *path) const {
|
||||||
|
// Shouldn't get here.
|
||||||
|
rError("in XmlValue::find(%s)", path);
|
||||||
|
return XmlValuePtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::read(const char *path, std::string *out) const {
|
||||||
|
XmlValuePtr value = find(path);
|
||||||
|
if (!value) return false;
|
||||||
|
|
||||||
|
*out = value->text();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::read(const char *path, int *out) const {
|
||||||
|
XmlValuePtr value = find(path);
|
||||||
|
if (!value) return false;
|
||||||
|
|
||||||
|
*out = atoi(value->text().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::read(const char *path, long *out) const {
|
||||||
|
XmlValuePtr value = find(path);
|
||||||
|
if (!value) return false;
|
||||||
|
|
||||||
|
*out = atol(value->text().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::read(const char *path, double *out) const {
|
||||||
|
XmlValuePtr value = find(path);
|
||||||
|
if (!value) return false;
|
||||||
|
|
||||||
|
*out = atof(value->text().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::read(const char *path, bool *out) const {
|
||||||
|
XmlValuePtr value = find(path);
|
||||||
|
if (!value) return false;
|
||||||
|
|
||||||
|
*out = atoi(value->text().c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::readB64(const char *path, unsigned char *data, int length) const {
|
||||||
|
XmlValuePtr value = find(path);
|
||||||
|
if (!value) return false;
|
||||||
|
|
||||||
|
std::string s = value->text();
|
||||||
|
s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
|
||||||
|
s.erase(s.find_last_not_of("=") + 1);
|
||||||
|
|
||||||
|
int decodedSize = B64ToB256Bytes(s.size());
|
||||||
|
if (decodedSize != length) {
|
||||||
|
rError("decoding bytes len %d, expecting output len %d, got %d", s.size(),
|
||||||
|
length, decodedSize);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!B64StandardDecode(data, (unsigned char *)s.data(), s.size())) {
|
||||||
|
rError("B64 decode failure on \"%s\"", s.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XmlValue::read(const char *path, rel::Interface *out) const {
|
||||||
|
XmlValuePtr node = find(path);
|
||||||
|
if (!node) return false;
|
||||||
|
|
||||||
|
bool ok = node->read("name", &out->name()) &&
|
||||||
|
node->read("major", &out->current()) &&
|
||||||
|
node->read("minor", &out->revision());
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string safeValueForNode(const tinyxml2::XMLElement *element) {
|
||||||
|
std::string value;
|
||||||
|
if (element == NULL) return value;
|
||||||
|
|
||||||
|
const tinyxml2::XMLNode *child = element->FirstChild();
|
||||||
|
if (child) {
|
||||||
|
const tinyxml2::XMLText *childText = child->ToText();
|
||||||
|
if (childText) value = childText->Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
class XmlNode : virtual public XmlValue {
|
||||||
|
const tinyxml2::XMLElement *element;
|
||||||
|
|
||||||
|
public:
|
||||||
|
XmlNode(const tinyxml2::XMLElement *element_)
|
||||||
|
: XmlValue(safeValueForNode(element_)), element(element_) {}
|
||||||
|
|
||||||
|
virtual ~XmlNode() {}
|
||||||
|
|
||||||
|
virtual XmlValuePtr find(const char *name) const {
|
||||||
|
if (name[0] == '@') {
|
||||||
|
const char *value = element->Attribute(name + 1);
|
||||||
|
if (value)
|
||||||
|
return XmlValuePtr(new XmlValue(value));
|
||||||
|
else
|
||||||
|
return XmlValuePtr();
|
||||||
|
} else {
|
||||||
|
const tinyxml2::XMLElement *el = element->FirstChildElement(name);
|
||||||
|
if (el)
|
||||||
|
return XmlValuePtr(new XmlNode(el));
|
||||||
|
else
|
||||||
|
return XmlValuePtr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct XmlReader::XmlReaderData {
|
||||||
|
shared_ptr<tinyxml2::XMLDocument> doc;
|
||||||
|
};
|
||||||
|
|
||||||
|
XmlReader::XmlReader() : pd(new XmlReaderData()) {}
|
||||||
|
|
||||||
|
XmlReader::~XmlReader() {}
|
||||||
|
|
||||||
|
bool XmlReader::load(const char *fileName) {
|
||||||
|
pd->doc.reset(new tinyxml2::XMLDocument());
|
||||||
|
|
||||||
|
auto err = pd->doc->LoadFile(fileName);
|
||||||
|
return err == tinyxml2::XML_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlValuePtr XmlReader::operator[](const char *name) const {
|
||||||
|
tinyxml2::XMLNode *node = pd->doc->FirstChildElement(name);
|
||||||
|
if (node == NULL) {
|
||||||
|
rError("Xml node %s not found", name);
|
||||||
|
return XmlValuePtr(new XmlValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
tinyxml2::XMLElement *element = node->ToElement();
|
||||||
|
if (element == NULL) {
|
||||||
|
rError("Xml node %s not element", name);
|
||||||
|
return XmlValuePtr(new XmlValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return XmlValuePtr(new XmlNode(element));
|
||||||
|
}
|
72
encfs/XmlReader.h
Normal file
72
encfs/XmlReader.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Author: Valient Gough <vgough@pobox.com>
|
||||||
|
*
|
||||||
|
*****************************************************************************
|
||||||
|
* Copyright (c) 2012, Valient Gough
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _XmlReader_incl_
|
||||||
|
#define _XmlReader_incl_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "Interface.h"
|
||||||
|
#include "shared_ptr.h"
|
||||||
|
|
||||||
|
class XmlValue;
|
||||||
|
typedef shared_ptr<XmlValue> XmlValuePtr;
|
||||||
|
|
||||||
|
class XmlValue {
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
XmlValue() {}
|
||||||
|
|
||||||
|
XmlValue(const std::string &value) { this->value = value; }
|
||||||
|
virtual ~XmlValue();
|
||||||
|
|
||||||
|
XmlValuePtr operator[](const char *path) const;
|
||||||
|
|
||||||
|
const std::string &text() const { return value; }
|
||||||
|
|
||||||
|
bool read(const char *path, std::string *out) const;
|
||||||
|
bool readB64(const char *path, unsigned char *out, int length) const;
|
||||||
|
|
||||||
|
bool read(const char *path, int *out) const;
|
||||||
|
bool read(const char *path, long *out) const;
|
||||||
|
bool read(const char *path, double *out) const;
|
||||||
|
bool read(const char *path, bool *out) const;
|
||||||
|
|
||||||
|
bool read(const char *path, rel::Interface *out) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual XmlValuePtr find(const char *name) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class XmlReader {
|
||||||
|
public:
|
||||||
|
XmlReader();
|
||||||
|
~XmlReader();
|
||||||
|
|
||||||
|
bool load(const char *fileName);
|
||||||
|
|
||||||
|
XmlValuePtr operator[](const char *name) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct XmlReaderData;
|
||||||
|
shared_ptr<XmlReaderData> pd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -20,8 +20,11 @@
|
|||||||
|
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <rlog/rlog.h>
|
||||||
|
|
||||||
// change between two powers of two, stored as the low bits of the bytes in the
|
// change between two powers of two, stored as the low bits of the bytes in the
|
||||||
// arrays.
|
// arrays.
|
||||||
// It is the caller's responsibility to make sure the output array is large
|
// It is the caller's responsibility to make sure the output array is large
|
||||||
@ -177,3 +180,99 @@ void AsciiToB32(unsigned char *out, const unsigned char *in, int length) {
|
|||||||
*out++ = (unsigned char)lch;
|
*out++ = (unsigned char)lch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define WHITESPACE 64
|
||||||
|
#define EQUALS 65
|
||||||
|
#define INVALID 66
|
||||||
|
|
||||||
|
static const unsigned char d[] = {
|
||||||
|
66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66,
|
||||||
|
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
|
||||||
|
66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53, 54,
|
||||||
|
55, 56, 57, 58, 59, 60, 61, 66, 66, // 50-59
|
||||||
|
66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||||
|
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66,
|
||||||
|
66, 66, 66, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 100-109
|
||||||
|
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
|
||||||
|
|
||||||
|
bool B64StandardDecode(unsigned char *out, const unsigned char *in, int inLen) {
|
||||||
|
const unsigned char *end = in + inLen;
|
||||||
|
size_t buf = 1;
|
||||||
|
|
||||||
|
while (in < end) {
|
||||||
|
unsigned char v = *in++;
|
||||||
|
if (v > 'z') {
|
||||||
|
rError("Invalid character: %d", (unsigned int)v);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned char c = d[v];
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case WHITESPACE:
|
||||||
|
continue; /* skip whitespace */
|
||||||
|
case INVALID:
|
||||||
|
rError("Invalid character: %d", (unsigned int)v);
|
||||||
|
return false; /* invalid input, return error */
|
||||||
|
case EQUALS: /* pad character, end of data */
|
||||||
|
in = end;
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
buf = buf << 6 | c;
|
||||||
|
|
||||||
|
/* If the buffer is full, split it into bytes */
|
||||||
|
if (buf & 0x1000000) {
|
||||||
|
*out++ = buf >> 16;
|
||||||
|
*out++ = buf >> 8;
|
||||||
|
*out++ = buf;
|
||||||
|
buf = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf & 0x40000) {
|
||||||
|
*out++ = buf >> 10;
|
||||||
|
*out++ = buf >> 2;
|
||||||
|
} else if (buf & 0x1000) {
|
||||||
|
*out++ = buf >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lookup table for encoding
|
||||||
|
// If you want to use an alternate alphabet, change the characters here
|
||||||
|
const static char encodeLookup[] =
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
std::string B64StandardEncode(std::vector<unsigned char> inputBuffer) {
|
||||||
|
std::string encodedString;
|
||||||
|
encodedString.reserve(B256ToB64Bytes(inputBuffer.size()));
|
||||||
|
long temp;
|
||||||
|
std::vector<unsigned char>::iterator cursor = inputBuffer.begin();
|
||||||
|
for (size_t idx = 0; idx < inputBuffer.size() / 3; idx++) {
|
||||||
|
temp = (*cursor++) << 16; // Convert to big endian
|
||||||
|
temp += (*cursor++) << 8;
|
||||||
|
temp += (*cursor++);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x00FC0000) >> 18]);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x0003F000) >> 12]);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x00000FC0) >> 6]);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x0000003F)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (inputBuffer.size() % 3) {
|
||||||
|
case 1:
|
||||||
|
temp = (*cursor++) << 16; // Convert to big endian
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x00FC0000) >> 18]);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x0003F000) >> 12]);
|
||||||
|
encodedString.append(2, '=');
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
temp = (*cursor++) << 16; // Convert to big endian
|
||||||
|
temp += (*cursor++) << 8;
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x00FC0000) >> 18]);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x0003F000) >> 12]);
|
||||||
|
encodedString.append(1, encodeLookup[(temp & 0x00000FC0) >> 6]);
|
||||||
|
encodedString.append(1, '=');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return encodedString;
|
||||||
|
}
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#ifndef _base64_incl_
|
#ifndef _base64_incl_
|
||||||
#define _base64_incl_
|
#define _base64_incl_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
inline int B64ToB256Bytes(int numB64Bytes) {
|
inline int B64ToB256Bytes(int numB64Bytes) {
|
||||||
return (numB64Bytes * 6) / 8; // round down
|
return (numB64Bytes * 6) / 8; // round down
|
||||||
}
|
}
|
||||||
@ -62,4 +65,11 @@ void AsciiToB64(unsigned char *out, const unsigned char *in, int length);
|
|||||||
void AsciiToB32(unsigned char *buf, int length);
|
void AsciiToB32(unsigned char *buf, int length);
|
||||||
void AsciiToB32(unsigned char *out, const unsigned char *in, int length);
|
void AsciiToB32(unsigned char *out, const unsigned char *in, int length);
|
||||||
|
|
||||||
|
// Decode standard B64 into the output array.
|
||||||
|
// Used only to decode legacy Boost XML serialized config format.
|
||||||
|
// The output size must be at least B64ToB256Bytes(inputLen).
|
||||||
|
bool B64StandardDecode(unsigned char *out, const unsigned char *in, int inputLen);
|
||||||
|
|
||||||
|
std::string B64StandardEncode(std::vector<unsigned char> input);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
#ifndef BOOST_VERSIONING_INCL
|
|
||||||
#define BOOST_VERSIONING_INCL
|
|
||||||
|
|
||||||
// This header stores workaround code for dealing with incompatible changes
|
|
||||||
// made to boost archive/serialization classes.
|
|
||||||
|
|
||||||
#if (BOOST_VERSION <= 104100)
|
|
||||||
// Easy case, boost archive serial numbers are sizeof(int)
|
|
||||||
BOOST_CLASS_VERSION(EncFSConfig, V6SubVersion)
|
|
||||||
#else
|
|
||||||
// starting with boost 1.42, serial numbers change to 8-bit. However to make
|
|
||||||
// things tricker, the internal comparison is more like 16bit, which makes
|
|
||||||
// writing backward compatible code very tricky.
|
|
||||||
|
|
||||||
// We make a partial specialization of the iserializer class to remove the
|
|
||||||
// version number checking which would otherwise cause boost::serialization to
|
|
||||||
// throw an exception if it came across a version that was greater then what
|
|
||||||
// we specify in BOOST_CLASS_VERSION below. Without this, manual editing
|
|
||||||
// of the file is needed before boost will allow us to read it.
|
|
||||||
|
|
||||||
BOOST_CLASS_VERSION(EncFSConfig, 20)
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace archive {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// Specialize iserializer class in order to get rid of version check
|
|
||||||
template <class Archive>
|
|
||||||
class iserializer<Archive, EncFSConfig> : public basic_iserializer {
|
|
||||||
private:
|
|
||||||
virtual void destroy(/*const*/ void *address) const {
|
|
||||||
boost::serialization::access::destroy(static_cast<EncFSConfig *>(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit iserializer()
|
|
||||||
: basic_iserializer(boost::serialization::singleton<
|
|
||||||
BOOST_DEDUCED_TYPENAME boost::serialization::
|
|
||||||
type_info_implementation<
|
|
||||||
EncFSConfig>::type>::get_const_instance()) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual BOOST_DLLEXPORT void load_object_data(
|
|
||||||
basic_iarchive &ar, void *x,
|
|
||||||
const unsigned int file_version) const BOOST_USED;
|
|
||||||
virtual bool class_info() const {
|
|
||||||
return boost::serialization::implementation_level<EncFSConfig>::value >=
|
|
||||||
boost::serialization::object_class_info;
|
|
||||||
}
|
|
||||||
virtual bool tracking(const unsigned int /* flags */) const {
|
|
||||||
return boost::serialization::tracking_level<EncFSConfig>::value ==
|
|
||||||
boost::serialization::track_always ||
|
|
||||||
(boost::serialization::tracking_level<EncFSConfig>::value ==
|
|
||||||
boost::serialization::track_selectively &&
|
|
||||||
serialized_as_pointer());
|
|
||||||
}
|
|
||||||
virtual version_type version() const {
|
|
||||||
return version_type(::boost::serialization::version<EncFSConfig>::value);
|
|
||||||
}
|
|
||||||
virtual bool is_polymorphic() const {
|
|
||||||
return boost::is_polymorphic<EncFSConfig>::value;
|
|
||||||
}
|
|
||||||
virtual ~iserializer(){};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Archive>
|
|
||||||
BOOST_DLLEXPORT void iserializer<Archive, EncFSConfig>::load_object_data(
|
|
||||||
basic_iarchive &ar, void *x, const unsigned int file_version) const {
|
|
||||||
boost::serialization::serialize_adl(
|
|
||||||
boost::serialization::smart_cast_reference<Archive &>(ar),
|
|
||||||
*static_cast<EncFSConfig *>(x), file_version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // BOOST_VERSIONING_INCL
|
|
@ -167,7 +167,7 @@ static int showInfo(int argc, char **argv) {
|
|||||||
string rootDir = argv[1];
|
string rootDir = argv[1];
|
||||||
if (!checkDir(rootDir)) return EXIT_FAILURE;
|
if (!checkDir(rootDir)) return EXIT_FAILURE;
|
||||||
|
|
||||||
shared_ptr<EncFSConfig> config(new EncFSConfig);
|
EncFSConfig* config = new EncFSConfig;
|
||||||
ConfigType type = readConfig(rootDir, config);
|
ConfigType type = readConfig(rootDir, config);
|
||||||
|
|
||||||
// show information stored in config..
|
// show information stored in config..
|
||||||
@ -617,7 +617,7 @@ static int do_chpasswd(bool useStdin, bool annotate, bool checkOnly, int argc, c
|
|||||||
string rootDir = argv[1];
|
string rootDir = argv[1];
|
||||||
if (!checkDir(rootDir)) return EXIT_FAILURE;
|
if (!checkDir(rootDir)) return EXIT_FAILURE;
|
||||||
|
|
||||||
shared_ptr<EncFSConfig> config(new EncFSConfig);
|
EncFSConfig* config = new EncFSConfig;
|
||||||
ConfigType cfgType = readConfig(rootDir, config);
|
ConfigType cfgType = readConfig(rootDir, config);
|
||||||
|
|
||||||
if (cfgType == Config_None) {
|
if (cfgType == Config_None) {
|
||||||
|
@ -16,12 +16,9 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rlog/Error.h>
|
|
||||||
#include <rlog/RLogChannel.h>
|
|
||||||
#include <rlog/StdioNode.h>
|
|
||||||
#include <rlog/rlog.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -29,6 +26,11 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <rlog/Error.h>
|
||||||
|
#include <rlog/RLogChannel.h>
|
||||||
|
#include <rlog/StdioNode.h>
|
||||||
|
#include <rlog/rlog.h>
|
||||||
|
|
||||||
#include "BlockNameIO.h"
|
#include "BlockNameIO.h"
|
||||||
#include "Cipher.h"
|
#include "Cipher.h"
|
||||||
#include "CipherKey.h"
|
#include "CipherKey.h"
|
||||||
@ -132,8 +134,9 @@ static bool testNameCoding(DirNode &dirNode, bool verbose) {
|
|||||||
|
|
||||||
bool runTests(const shared_ptr<Cipher> &cipher, bool verbose) {
|
bool runTests(const shared_ptr<Cipher> &cipher, bool verbose) {
|
||||||
// create a random key
|
// create a random key
|
||||||
if (verbose)
|
if (verbose) {
|
||||||
cerr << "Generating new key, output will be different on each run\n\n";
|
cerr << "Generating new key, output will be different on each run\n\n";
|
||||||
|
}
|
||||||
CipherKey key = cipher->newRandomKey();
|
CipherKey key = cipher->newRandomKey();
|
||||||
|
|
||||||
if (verbose) cerr << "Testing key save / restore :";
|
if (verbose) cerr << "Testing key save / restore :";
|
||||||
@ -173,18 +176,17 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose) {
|
|||||||
cfg.assignKeyData(keyBuf, encodedKeySize);
|
cfg.assignKeyData(keyBuf, encodedKeySize);
|
||||||
|
|
||||||
// save config
|
// save config
|
||||||
string data;
|
auto name = std::tmpnam(nullptr);
|
||||||
{
|
{
|
||||||
ostringstream st;
|
auto ok = writeV6Config(name, &cfg);
|
||||||
st << cfg;
|
rAssert(ok == true);
|
||||||
data = st.str();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read back in and check everything..
|
// read back in and check everything..
|
||||||
EncFSConfig cfg2;
|
EncFSConfig cfg2;
|
||||||
{
|
{
|
||||||
istringstream st(data);
|
auto ok = readV6Config(name, &cfg2, nullptr);
|
||||||
st >> cfg2;
|
rAssert(ok == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check..
|
// check..
|
||||||
|
Loading…
Reference in New Issue
Block a user