mirror of
https://github.com/vgough/encfs.git
synced 2024-11-21 23:43:26 +01:00
Replace boost::serialization.
Boost::serialization and the corresponding internal configuration structure are replace with a protocol buffer message. Dropped support for writing old configuration files. Only the new format can be written. A password change will write a newly formatted configuration file, but does not delete the old file. Version bumped to 1.8 git-svn-id: http://encfs.googlecode.com/svn/trunk@80 db9cf616-1c43-0410-9cb8-a902689de0d6
This commit is contained in:
parent
67821fb209
commit
67c72dfe99
28
ChangeLog
28
ChangeLog
@ -1,3 +1,31 @@
|
||||
Thu Mar 22 2012 Valient Gough <vgough@pobox.com>
|
||||
* skip name collision test
|
||||
* bump version to 1.8.0
|
||||
* drop boost serialization from requirements
|
||||
|
||||
Sun Mar 4 2012 Valient Gough <vgough@pobox.com>
|
||||
* bump ld version
|
||||
* replace EncFSConfig with protocol buffer
|
||||
|
||||
Fri Mar 2 2012 Valient Gough <vgough@pobox.com>
|
||||
* replace boost serialization with protocol buffer support
|
||||
|
||||
Wed Feb 29 2012 Valient Gough <vgough@pobox.com>
|
||||
* switch to OpenSSL B64 decode to be comptible with boost serialization
|
||||
* implement v6 config reader using XML reader based on tinyxml
|
||||
|
||||
Mon Jan 2 2012 Valient Gough <vgough@pobox.com>
|
||||
* test for name case collisions in b64 coding
|
||||
|
||||
Thu Dec 29 2011 Valient Gough <vgough@pobox.com>
|
||||
* add base32 support for name encoding
|
||||
|
||||
Thu Mar 3 2011 Valient Gough <vgough@pobox.com>
|
||||
* update copyright on BlockNameIO
|
||||
|
||||
Thu Dec 29 2011 Valient Gough <vgough@pobox.com>
|
||||
* revert fuse_unmount change, wasn't working
|
||||
|
||||
Wed Dec 28 2011 Valient Gough <vgough@pobox.com>
|
||||
* remove m4-local
|
||||
* bump version to 1.7.5
|
||||
|
18
configure.ac
18
configure.ac
@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(encfs/encfs.h) dnl a source file from your sub dir
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AM_INIT_AUTOMAKE(encfs, 1.7.5) dnl searches for some needed programs
|
||||
AM_INIT_AUTOMAKE(encfs, 1.8.0) dnl searches for some needed programs
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
@ -48,7 +48,6 @@ AX_PTHREAD
|
||||
|
||||
AX_BOOST_BASE([1.34])
|
||||
AX_BOOST_SYSTEM
|
||||
AX_BOOST_SERIALIZATION
|
||||
AX_BOOST_FILESYSTEM
|
||||
|
||||
dnl Need to include any user specified flags in the tests below, as they might
|
||||
@ -203,6 +202,21 @@ if test "$with_rlog" = "test" && test "x$RLOG_LIBS" = "x"; then
|
||||
[AC_MSG_ERROR([EncFS depends on librlog])])
|
||||
fi
|
||||
|
||||
# find Protocol Buffers
|
||||
PKG_CHECK_MODULES(PROTOBUF, protobuf >= 2.0)
|
||||
AC_PATH_PROG(PROTOC, protoc, [no])
|
||||
if test "$PROTOC" == "no"; then
|
||||
AC_MSG_FAILURE([Protocol Buffers compiler 'protoc' is required to build.])
|
||||
fi
|
||||
|
||||
# find TinyXML
|
||||
AC_LANG_PUSH([C++])
|
||||
CPPFLAGS="$CPPFLAGS -DTIXML_USE_STL"
|
||||
AC_CHECK_HEADER([tinyxml.h],,[AC_MSG_ERROR([tinyxml.h not found])])
|
||||
AC_CHECK_LIB([tinyxml],[main],,
|
||||
[AC_MSG_ERROR([you must install libtinyxml dev])])
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
# look for pod2man program for building man pages
|
||||
AC_PATH_PROG(POD2MAN, pod2man, [no])
|
||||
AC_PATH_PROG(POD2HTML, pod2html, [no])
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "BlockFileIO.h"
|
||||
|
||||
#include "MemoryPool.h"
|
||||
#include "config.pb.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <rlog/rlog.h>
|
||||
@ -38,7 +39,7 @@ static void clearCache( IORequest &req, int blockSize )
|
||||
|
||||
BlockFileIO::BlockFileIO( int blockSize, const FSConfigPtr &cfg )
|
||||
: _blockSize( blockSize )
|
||||
, _allowHoles( cfg->config->allowHoles )
|
||||
, _allowHoles( cfg->config->allow_holes() )
|
||||
{
|
||||
rAssert( _blockSize > 1 );
|
||||
_cache.data = new unsigned char [ _blockSize ];
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace rlog;
|
||||
using namespace rel;
|
||||
using namespace boost;
|
||||
|
||||
static RLogChannel * Info = DEF_CHANNEL( "info/nameio", Log_Info );
|
||||
@ -94,16 +93,16 @@ Interface BlockNameIO::CurrentInterface(bool caseSensitive)
|
||||
{
|
||||
// implement major version 4 plus support for two prior versions
|
||||
if (caseSensitive)
|
||||
return Interface("nameio/block32", 4, 0, 2);
|
||||
return makeInterface("nameio/block32", 4, 0, 2);
|
||||
else
|
||||
return Interface("nameio/block", 4, 0, 2);
|
||||
return makeInterface("nameio/block", 4, 0, 2);
|
||||
}
|
||||
|
||||
BlockNameIO::BlockNameIO( const rel::Interface &iface,
|
||||
BlockNameIO::BlockNameIO( const Interface &iface,
|
||||
const shared_ptr<Cipher> &cipher,
|
||||
const CipherKey &key, int blockSize,
|
||||
bool caseSensitiveEncoding )
|
||||
: _interface( iface.current() )
|
||||
: _interface( iface.major() )
|
||||
, _bs( blockSize )
|
||||
, _cipher( cipher )
|
||||
, _key( key )
|
||||
|
@ -33,15 +33,15 @@ class Cipher;
|
||||
class BlockNameIO : public NameIO
|
||||
{
|
||||
public:
|
||||
static rel::Interface CurrentInterface(bool caseSensitive = false);
|
||||
static Interface CurrentInterface(bool caseSensitive = false);
|
||||
|
||||
BlockNameIO( const rel::Interface &iface,
|
||||
BlockNameIO( const Interface &iface,
|
||||
const boost::shared_ptr<Cipher> &cipher,
|
||||
const CipherKey &key, int blockSize,
|
||||
bool caseSensitiveEncoding = false );
|
||||
virtual ~BlockNameIO();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
||||
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "SSL_Cipher.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace rel;
|
||||
using boost::shared_ptr;
|
||||
|
||||
#define REF_MODULE(TYPE) \
|
||||
@ -150,7 +149,7 @@ shared_ptr<Cipher> Cipher::New( const Interface &iface, int keyLen )
|
||||
for(it = gCipherMap->begin(); it != mapEnd; ++it)
|
||||
{
|
||||
// TODO: we should look for the newest implementation..
|
||||
if( it->second.iface.implements( iface ) )
|
||||
if( implements(it->second.iface, iface) )
|
||||
{
|
||||
CipherConstructor fn = it->second.constructor;
|
||||
// pass in requested interface..
|
||||
|
@ -42,14 +42,14 @@ class Cipher
|
||||
public:
|
||||
// if no key length was indicated when cipher was registered, then keyLen
|
||||
// <= 0 will be used.
|
||||
typedef boost::shared_ptr<Cipher> (*CipherConstructor)( const rel::Interface &iface,
|
||||
typedef boost::shared_ptr<Cipher> (*CipherConstructor)( const Interface &iface,
|
||||
int keyLenBits );
|
||||
|
||||
struct CipherAlgorithm
|
||||
{
|
||||
std::string name;
|
||||
std::string description;
|
||||
rel::Interface iface;
|
||||
Interface iface;
|
||||
Range keyLength;
|
||||
Range blockSize;
|
||||
};
|
||||
@ -59,7 +59,7 @@ public:
|
||||
static AlgorithmList GetAlgorithmList( bool includeHidden = false );
|
||||
|
||||
|
||||
static boost::shared_ptr<Cipher> New( const rel::Interface &iface,
|
||||
static boost::shared_ptr<Cipher> New( const Interface &iface,
|
||||
int keyLen = -1);
|
||||
static boost::shared_ptr<Cipher> New( const std::string &cipherName,
|
||||
int keyLen = -1 );
|
||||
@ -67,12 +67,12 @@ public:
|
||||
|
||||
static bool Register(const char *cipherName,
|
||||
const char *description,
|
||||
const rel::Interface &iface,
|
||||
const Interface &iface,
|
||||
CipherConstructor constructor,
|
||||
bool hidden = false);
|
||||
static bool Register(const char *cipherName,
|
||||
const char *description,
|
||||
const rel::Interface &iface,
|
||||
const Interface &iface,
|
||||
const Range &keyLength, const Range &blockSize,
|
||||
CipherConstructor constructor,
|
||||
bool hidden = false);
|
||||
@ -81,7 +81,7 @@ public:
|
||||
Cipher();
|
||||
virtual ~Cipher();
|
||||
|
||||
virtual rel::Interface interface() const =0;
|
||||
virtual Interface interface() const =0;
|
||||
|
||||
// create a new key based on a password
|
||||
// if iterationCount == 0, then iteration count will be determined
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "Cipher.h"
|
||||
#include "MemoryPool.h"
|
||||
#include "config.pb.h"
|
||||
|
||||
#include <rlog/rlog.h>
|
||||
#include <rlog/Error.h>
|
||||
@ -34,7 +35,7 @@ using boost::shared_ptr;
|
||||
filesystem at the filesystem configuration level.
|
||||
When headers are disabled, 2:0 is compatible with version 1:0.
|
||||
*/
|
||||
static rel::Interface CipherFileIO_iface("FileIO/Cipher", 2, 0, 1);
|
||||
static Interface CipherFileIO_iface = makeInterface("FileIO/Cipher", 2, 0, 1);
|
||||
|
||||
const int HEADER_SIZE = 8; // 64 bit initialization vector..
|
||||
|
||||
@ -51,9 +52,9 @@ static bool checkSize( int fsBlockSize, int cipherBlockSize )
|
||||
|
||||
CipherFileIO::CipherFileIO( const shared_ptr<FileIO> &_base,
|
||||
const FSConfigPtr &cfg)
|
||||
: BlockFileIO( cfg->config->blockSize, cfg )
|
||||
: BlockFileIO( cfg->config->block_size(), cfg )
|
||||
, base( _base )
|
||||
, haveHeader( cfg->config->uniqueIV )
|
||||
, haveHeader( cfg->config->unique_iv() )
|
||||
, externalIV( 0 )
|
||||
, fileIV( 0 )
|
||||
, lastFlags( 0 )
|
||||
@ -65,7 +66,7 @@ CipherFileIO::CipherFileIO( const shared_ptr<FileIO> &_base,
|
||||
static bool warnOnce = false;
|
||||
|
||||
if(!warnOnce)
|
||||
warnOnce = checkSize( fsConfig->config->blockSize,
|
||||
warnOnce = checkSize( fsConfig->config->block_size(),
|
||||
fsConfig->cipher->cipherBlockSize() );
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ CipherFileIO::~CipherFileIO()
|
||||
{
|
||||
}
|
||||
|
||||
rel::Interface CipherFileIO::interface() const
|
||||
Interface CipherFileIO::interface() const
|
||||
{
|
||||
return CipherFileIO_iface;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
const FSConfigPtr &cfg);
|
||||
virtual ~CipherFileIO();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
virtual void setFileName( const char *fileName );
|
||||
virtual const char *getFileName() const;
|
||||
|
@ -690,7 +690,7 @@ int DirNode::link( const char *from, const char *to )
|
||||
rLog(Info, "link %s -> %s", fromCName.c_str(), toCName.c_str());
|
||||
|
||||
int res = -EPERM;
|
||||
if( fsConfig->config->externalIVChaining )
|
||||
if( fsConfig->config->external_iv() )
|
||||
{
|
||||
rLog(Info, "hard links not supported with external IV chaining!");
|
||||
} else
|
||||
@ -756,7 +756,7 @@ shared_ptr<FileNode> DirNode::findOrCreate( const char *plainName)
|
||||
plainName,
|
||||
(rootDir + cipherName).c_str()));
|
||||
|
||||
if(fsConfig->config->externalIVChaining)
|
||||
if(fsConfig->config->external_iv())
|
||||
node->setName(0, 0, iv);
|
||||
|
||||
rLog(Info, "created FileNode for %s", node->cipherName());
|
||||
|
@ -32,88 +32,37 @@ enum ConfigType
|
||||
{
|
||||
Config_None = 0,
|
||||
Config_Prehistoric,
|
||||
Config_V3,
|
||||
Config_V4,
|
||||
Config_V5,
|
||||
Config_V6
|
||||
Config_V3 = 3,
|
||||
Config_V4 = 4,
|
||||
Config_V5 = 5,
|
||||
Config_V6 = 6,
|
||||
Config_V7 = 7
|
||||
};
|
||||
|
||||
class EncFS_Opts;
|
||||
class Cipher;
|
||||
class NameIO;
|
||||
class EncfsConfig;
|
||||
|
||||
struct EncFSConfig
|
||||
{
|
||||
ConfigType cfgType;
|
||||
CipherKey getUserKey(const EncfsConfig &config, bool useStdin);
|
||||
CipherKey getUserKey(const EncfsConfig &config,
|
||||
const std::string &passwordProgram,
|
||||
const std::string &rootDir);
|
||||
|
||||
std::string creator;
|
||||
int subVersion;
|
||||
|
||||
// interface of cipher
|
||||
rel::Interface cipherIface;
|
||||
// interface used for file name coding
|
||||
rel::Interface nameIface;
|
||||
int keySize; // reported in bits
|
||||
int blockSize; // reported in bytes
|
||||
|
||||
std::vector<unsigned char> keyData;
|
||||
|
||||
std::vector<unsigned char> salt;
|
||||
int kdfIterations;
|
||||
long desiredKDFDuration;
|
||||
|
||||
int blockMACBytes; // MAC headers on blocks..
|
||||
int blockMACRandBytes; // number of random bytes in the block header
|
||||
|
||||
bool uniqueIV; // per-file Initialization Vector
|
||||
bool externalIVChaining; // IV seeding by filename IV chaining
|
||||
|
||||
bool chainedNameIV; // filename IV chaining
|
||||
bool allowHoles; // allow holes in files (implicit zero blocks)
|
||||
|
||||
EncFSConfig()
|
||||
: keyData()
|
||||
, salt()
|
||||
{
|
||||
cfgType = Config_None;
|
||||
subVersion = 0;
|
||||
blockMACBytes = 0;
|
||||
blockMACRandBytes = 0;
|
||||
uniqueIV = false;
|
||||
externalIVChaining = false;
|
||||
chainedNameIV = false;
|
||||
allowHoles = false;
|
||||
|
||||
kdfIterations = 0;
|
||||
desiredKDFDuration = 500;
|
||||
}
|
||||
|
||||
CipherKey getUserKey(bool useStdin);
|
||||
CipherKey getUserKey(const std::string &passwordProgram,
|
||||
const std::string &rootDir);
|
||||
CipherKey getNewUserKey();
|
||||
CipherKey getNewUserKey(EncfsConfig &config, bool useStdin,
|
||||
const std::string &program, const std::string &rootDir);
|
||||
|
||||
boost::shared_ptr<Cipher> getCipher() const;
|
||||
boost::shared_ptr<Cipher> getCipher(const EncfsConfig &cfg);
|
||||
boost::shared_ptr<Cipher> getCipher(const Interface &iface, int keySize);
|
||||
|
||||
// deprecated
|
||||
void assignKeyData(const std::string &in);
|
||||
void assignKeyData(unsigned char *data, int length);
|
||||
void assignSaltData(unsigned char *data, int length);
|
||||
|
||||
unsigned char *getKeyData() const;
|
||||
unsigned char *getSaltData() const;
|
||||
|
||||
private:
|
||||
CipherKey makeKey(const char *password, int passwdLen);
|
||||
};
|
||||
|
||||
// helpers for serializing to/from a stream
|
||||
std::ostream &operator << (std::ostream &os, const EncFSConfig &cfg);
|
||||
std::istream &operator >> (std::istream &os, EncFSConfig &cfg);
|
||||
std::ostream &operator << (std::ostream &os, const EncfsConfig &cfg);
|
||||
std::istream &operator >> (std::istream &os, EncfsConfig &cfg);
|
||||
|
||||
// Filesystem state
|
||||
struct FSConfig
|
||||
{
|
||||
boost::shared_ptr<EncFSConfig> config;
|
||||
boost::shared_ptr<EncfsConfig> config;
|
||||
boost::shared_ptr<EncFS_Opts> opts;
|
||||
|
||||
boost::shared_ptr<Cipher> cipher;
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
FileIO();
|
||||
virtual ~FileIO();
|
||||
|
||||
virtual rel::Interface interface() const =0;
|
||||
virtual Interface interface() const =0;
|
||||
|
||||
// default implementation returns 1, meaning this is not block oriented.
|
||||
virtual int blockSize() const;
|
||||
|
@ -80,7 +80,7 @@ FileNode::FileNode(DirNode *parent_, const FSConfigPtr &cfg,
|
||||
shared_ptr<FileIO> rawIO( new RawFileIO( _cname ) );
|
||||
io = shared_ptr<FileIO>( new CipherFileIO( rawIO, fsConfig ));
|
||||
|
||||
if(cfg->config->blockMACBytes || cfg->config->blockMACRandBytes)
|
||||
if(cfg->config->block_mac_bytes() || cfg->config->block_mac_rand_bytes())
|
||||
io = shared_ptr<FileIO>(new MACFileIO(io, fsConfig));
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ bool FileNode::setName( const char *plaintextName_, const char *cipherName_,
|
||||
rDebug("calling setIV on %s", cipherName_);
|
||||
if(setIVFirst)
|
||||
{
|
||||
if(fsConfig->config->externalIVChaining && !setIV(io, iv))
|
||||
if(fsConfig->config->external_iv() && !setIV(io, iv))
|
||||
return false;
|
||||
|
||||
// now change the name..
|
||||
@ -151,7 +151,7 @@ bool FileNode::setName( const char *plaintextName_, const char *cipherName_,
|
||||
io->setFileName( cipherName_ );
|
||||
}
|
||||
|
||||
if(fsConfig->config->externalIVChaining && !setIV(io, iv))
|
||||
if(fsConfig->config->external_iv() && !setIV(io, iv))
|
||||
{
|
||||
_pname = oldPName;
|
||||
_cname = oldCName;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -99,41 +99,33 @@ struct EncFS_Opts
|
||||
/*
|
||||
Read existing config file. Looks for any supported configuration version.
|
||||
*/
|
||||
ConfigType readConfig( const std::string &rootDir,
|
||||
const boost::shared_ptr<EncFSConfig> &config );
|
||||
ConfigType readConfig( const std::string &rootDir, EncfsConfig &config );
|
||||
|
||||
/*
|
||||
Save the configuration. Saves back as the same configuration type as was
|
||||
read from.
|
||||
*/
|
||||
bool saveConfig( ConfigType type, const std::string &rootdir,
|
||||
const boost::shared_ptr<EncFSConfig> &config );
|
||||
bool saveConfig( const std::string &rootdir, const EncfsConfig &config );
|
||||
|
||||
class EncFS_Context;
|
||||
|
||||
RootPtr initFS( EncFS_Context *ctx, const boost::shared_ptr<EncFS_Opts> &opts );
|
||||
|
||||
RootPtr createV6Config( EncFS_Context *ctx,
|
||||
RootPtr createConfig( EncFS_Context *ctx,
|
||||
const boost::shared_ptr<EncFS_Opts> &opts );
|
||||
|
||||
void showFSInfo( const boost::shared_ptr<EncFSConfig> &config );
|
||||
void showFSInfo( const EncfsConfig &config );
|
||||
|
||||
bool readV4Config( const char *configFile,
|
||||
const boost::shared_ptr<EncFSConfig> &config,
|
||||
bool readV4Config( const char *configFile, EncfsConfig &config,
|
||||
struct ConfigInfo *);
|
||||
bool writeV4Config( const char *configFile,
|
||||
const boost::shared_ptr<EncFSConfig> &config);
|
||||
|
||||
bool readV5Config( const char *configFile,
|
||||
const boost::shared_ptr<EncFSConfig> &config,
|
||||
bool readV5Config( const char *configFile, EncfsConfig &config,
|
||||
struct ConfigInfo *);
|
||||
bool writeV5Config( const char *configFile,
|
||||
const boost::shared_ptr<EncFSConfig> &config);
|
||||
|
||||
bool readV6Config( const char *configFile,
|
||||
const boost::shared_ptr<EncFSConfig> &config,
|
||||
bool readV6Config( const char *configFile, EncfsConfig &config,
|
||||
struct ConfigInfo *);
|
||||
|
||||
bool readProtoConfig( const char *configFile, EncfsConfig &config,
|
||||
struct ConfigInfo *);
|
||||
bool writeV6Config( const char *configFile,
|
||||
const boost::shared_ptr<EncFSConfig> &config);
|
||||
|
||||
#endif
|
||||
|
@ -22,205 +22,69 @@
|
||||
#include <rlog/rlog.h>
|
||||
#include <rlog/RLogChannel.h>
|
||||
|
||||
using namespace rel;
|
||||
using namespace rlog;
|
||||
|
||||
static RLogChannel * Info = DEF_CHANNEL( "info/iface", Log_Info );
|
||||
|
||||
Interface::Interface(const char *name_, int Current, int Revision, int Age)
|
||||
: _name( name_ )
|
||||
, _current( Current )
|
||||
, _revision( Revision )
|
||||
, _age( Age )
|
||||
bool implements(const Interface &A, const Interface &B)
|
||||
{
|
||||
rLog(Info, "checking if %s(%i:%i:%i) implements %s(%i:%i:%i)",
|
||||
A.name().c_str(), A.major(), A.minor(), A.age(),
|
||||
B.name().c_str(), B.major(), B.minor(), B.age());
|
||||
|
||||
if( A.name() != B.name() )
|
||||
return false;
|
||||
|
||||
int currentDiff = A.major() - B.major();
|
||||
return ( currentDiff >= 0 && currentDiff <= (int)A.age() );
|
||||
}
|
||||
|
||||
Interface::Interface(const std::string &name_, int Current,
|
||||
int Revision, int Age)
|
||||
: _name( name_ )
|
||||
, _current( Current )
|
||||
, _revision( Revision )
|
||||
, _age( Age )
|
||||
Interface makeInterface(const char *name, int major, int minor, int age)
|
||||
{
|
||||
Interface iface;
|
||||
iface.set_name(name);
|
||||
iface.set_major(major);
|
||||
iface.set_minor(minor);
|
||||
iface.set_age(age);
|
||||
return iface;
|
||||
}
|
||||
|
||||
Interface::Interface(const Interface &src)
|
||||
: _name( src._name )
|
||||
, _current( src._current )
|
||||
, _revision( src._revision )
|
||||
, _age( src._age )
|
||||
ConfigVar & operator << (ConfigVar &dst, const Interface &iface)
|
||||
{
|
||||
}
|
||||
|
||||
Interface::Interface()
|
||||
: _current( 0 )
|
||||
, _revision( 0 )
|
||||
, _age( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
Interface &Interface::operator = (const Interface &src)
|
||||
{
|
||||
_name = src._name;
|
||||
_current = src._current;
|
||||
_revision = src._revision;
|
||||
_age = src._age;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string & Interface::name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
std::string & Interface::name()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
int Interface::current() const
|
||||
{
|
||||
return _current;
|
||||
}
|
||||
|
||||
int &Interface::current()
|
||||
{
|
||||
return _current;
|
||||
}
|
||||
|
||||
int Interface::revision() const
|
||||
{
|
||||
return _revision;
|
||||
}
|
||||
|
||||
int &Interface::revision()
|
||||
{
|
||||
return _revision;
|
||||
}
|
||||
|
||||
int Interface::age() const
|
||||
{
|
||||
return _age;
|
||||
}
|
||||
|
||||
int &Interface::age()
|
||||
{
|
||||
return _age;
|
||||
}
|
||||
|
||||
bool operator == (const Interface &A, const Interface &B)
|
||||
{
|
||||
return ( A.name() == B.name()
|
||||
&& A.current() == B.current()
|
||||
&& A.revision() == B.revision()
|
||||
&& A.age() == B.age() );
|
||||
}
|
||||
|
||||
bool operator != (const Interface &A, const Interface &B)
|
||||
{
|
||||
return ( A.name() != B.name()
|
||||
|| A.current() != B.current()
|
||||
|| A.revision() != B.revision()
|
||||
|| A.age() != B.age() );
|
||||
}
|
||||
|
||||
// zero branch method of getting comparison sign..
|
||||
// tricky.. makes assumptions
|
||||
#if 0
|
||||
static int sign( int a, int b )
|
||||
{
|
||||
unsigned int ab = ((unsigned int)(a - b)) >> 31;
|
||||
unsigned int ba = ((unsigned int)(b - a)) >> 31;
|
||||
|
||||
return 1 + ba - ab;
|
||||
}
|
||||
#else
|
||||
// simple, easy to check, unlikely to break due to unforseen events..
|
||||
static int sign( int a, int b )
|
||||
{
|
||||
if(a < b)
|
||||
return 0;
|
||||
else if(a == b)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int diffSum( const Interface &A, const Interface &B )
|
||||
{
|
||||
int cS = sign( A.current() , B.current() );
|
||||
int aS = sign( A.age(), B.age() );
|
||||
int rS = sign( A.revision(), B.revision() );
|
||||
|
||||
return (cS * 3 + aS) * 3 + rS;
|
||||
}
|
||||
|
||||
const int EqualVersion = (1 * 3 + 1) * 3 + 1;
|
||||
|
||||
bool Interface::implements(const Interface &B) const
|
||||
{
|
||||
rLog(Info, "checking if %s(%i:%i:%i) implements %s(%i:%i:%i)",
|
||||
name().c_str(), current(), revision(), age(),
|
||||
B.name().c_str(), B.current(), B.revision(), B.age());
|
||||
|
||||
if( name() != B.name() )
|
||||
return false;
|
||||
|
||||
int currentDiff = current() - B.current();
|
||||
return ( currentDiff >= 0 && currentDiff <= age() );
|
||||
}
|
||||
|
||||
|
||||
bool operator < (const Interface &A, const Interface &B)
|
||||
{
|
||||
if( A.name() == B.name() )
|
||||
{
|
||||
return ( diffSum(A,B) < EqualVersion );
|
||||
} else
|
||||
return A.name() < B.name();
|
||||
}
|
||||
|
||||
bool operator > (const Interface &A, const Interface &B)
|
||||
{
|
||||
if( A.name() == B.name() )
|
||||
{
|
||||
return ( diffSum(A,B) > EqualVersion );
|
||||
} else
|
||||
return A.name() < B.name();
|
||||
}
|
||||
|
||||
bool operator <= (const Interface &A, const Interface &B)
|
||||
{
|
||||
if( A.name() == B.name() )
|
||||
{
|
||||
return ( diffSum(A,B) <= EqualVersion );
|
||||
} else
|
||||
return A.name() < B.name();
|
||||
}
|
||||
|
||||
bool operator >= (const Interface &A, const Interface &B)
|
||||
{
|
||||
if( A.name() == B.name() )
|
||||
{
|
||||
return ( diffSum(A,B) >= EqualVersion );
|
||||
} else
|
||||
return A.name() < B.name();
|
||||
}
|
||||
|
||||
|
||||
ConfigVar & operator << (ConfigVar &dst, const rel::Interface &iface)
|
||||
{
|
||||
dst << iface.name() << iface.current() << iface.revision() << iface.age();
|
||||
return dst;
|
||||
dst << iface.name() << (int)iface.major() << (int)iface.minor() << (int)iface.age();
|
||||
return dst;
|
||||
}
|
||||
|
||||
const ConfigVar & operator >> (const ConfigVar &src, Interface &iface)
|
||||
{
|
||||
src >> iface.name();
|
||||
src >> iface.current();
|
||||
src >> iface.revision();
|
||||
src >> iface.age();
|
||||
src >> *iface.mutable_name();
|
||||
int major, minor, age;
|
||||
src >> major >> minor >> age;
|
||||
iface.set_major(major);
|
||||
iface.set_minor(minor);
|
||||
iface.set_age(age);
|
||||
return src;
|
||||
}
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &src, Interface &iface)
|
||||
{
|
||||
(*src)["name"] >> *iface.mutable_name();
|
||||
int major, minor;
|
||||
(*src)["major"] >> major;
|
||||
(*src)["minor"] >> minor;
|
||||
iface.set_major(major);
|
||||
iface.set_minor(minor);
|
||||
return src;
|
||||
}
|
||||
|
||||
bool operator != (const Interface &a, const Interface &b)
|
||||
{
|
||||
if (a.major() != b.major())
|
||||
return true;
|
||||
|
||||
if (a.minor() != b.minor())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -19,66 +19,23 @@
|
||||
#define _Interface_incl_
|
||||
|
||||
#include <string>
|
||||
#include "XmlReader.h"
|
||||
#include "config.pb.h"
|
||||
|
||||
// check if A implements the interface described by B.
|
||||
// Note that implements(A, B) is not the same as implements(B, A)
|
||||
// This checks the current() version and age() against B.current() for
|
||||
// compatibility. Even if A.implements(B) is true, B > A may also be
|
||||
// true, meaning B is a newer revision of the interface then A.
|
||||
bool implements( const Interface &a, const Interface &b );
|
||||
Interface makeInterface( const char *name, int major, int minor, int age );
|
||||
|
||||
// Reae operation
|
||||
class ConfigVar;
|
||||
const ConfigVar & operator >> (const ConfigVar &, Interface &);
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &, Interface &);
|
||||
|
||||
// part of REL library..
|
||||
namespace rel
|
||||
{
|
||||
|
||||
class Interface
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
Version numbers as described by libtool: info://libtool/versioning
|
||||
Current - the most recent interface api that is implemented.
|
||||
Revision - the implementation number of the current interface.
|
||||
Age - the difference between the newest and oldest interfaces that
|
||||
are implemented.
|
||||
*/
|
||||
Interface( const char *name, int Current, int Revision, int Age );
|
||||
Interface( const std::string &name, int Current, int Revision, int Age);
|
||||
Interface(const Interface &src);
|
||||
Interface();
|
||||
|
||||
// check if we implement the interface described by B.
|
||||
// Note that A.implements(B) is not the same as B.implements(A)
|
||||
// This checks the current() version and age() against B.current() for
|
||||
// compatibility. Even if A.implements(B) is true, B > A may also be
|
||||
// true, meaning B is a newer revision of the interface then A.
|
||||
bool implements( const Interface &dst ) const;
|
||||
|
||||
const std::string &name() const;
|
||||
int current() const;
|
||||
int revision() const;
|
||||
int age() const;
|
||||
|
||||
std::string &name();
|
||||
int ¤t();
|
||||
int &revision();
|
||||
int &age();
|
||||
|
||||
Interface &operator = ( const Interface &src );
|
||||
|
||||
private:
|
||||
std::string _name;
|
||||
int _current;
|
||||
int _revision;
|
||||
int _age;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
ConfigVar & operator << (ConfigVar &, const rel::Interface &);
|
||||
const ConfigVar & operator >> (const ConfigVar &, rel::Interface &);
|
||||
|
||||
bool operator < (const rel::Interface &A, const rel::Interface &B);
|
||||
bool operator > (const rel::Interface &A, const rel::Interface &B);
|
||||
bool operator <= (const rel::Interface &A, const rel::Interface &B);
|
||||
bool operator >= (const rel::Interface &A, const rel::Interface &B);
|
||||
bool operator == (const rel::Interface &A, const rel::Interface &B);
|
||||
bool operator != (const rel::Interface &A, const rel::Interface &B);
|
||||
bool operator != (const Interface &a, const Interface &b);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "MemoryPool.h"
|
||||
#include "FileUtils.h"
|
||||
#include "config.pb.h"
|
||||
|
||||
#include <rlog/rlog.h>
|
||||
#include <rlog/Error.h>
|
||||
@ -29,7 +30,6 @@
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace rlog;
|
||||
using namespace rel;
|
||||
using namespace std;
|
||||
using boost::shared_ptr;
|
||||
using boost::dynamic_pointer_cast;
|
||||
@ -48,13 +48,13 @@ static RLogChannel *Info = DEF_CHANNEL("info/MACFileIO", Log_Info);
|
||||
// compatible, except at a high level by checking a revision number for the
|
||||
// filesystem...
|
||||
//
|
||||
static rel::Interface MACFileIO_iface("FileIO/MAC", 2, 1, 0);
|
||||
static Interface MACFileIO_iface = makeInterface("FileIO/MAC", 2, 1, 0);
|
||||
|
||||
int dataBlockSize(const FSConfigPtr &cfg)
|
||||
{
|
||||
return cfg->config->blockSize
|
||||
- cfg->config->blockMACBytes
|
||||
- cfg->config->blockMACRandBytes;
|
||||
return cfg->config->block_size()
|
||||
- cfg->config->block_mac_bytes()
|
||||
- cfg->config->block_mac_rand_bytes();
|
||||
}
|
||||
|
||||
MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base,
|
||||
@ -63,23 +63,23 @@ MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base,
|
||||
, base( _base )
|
||||
, cipher( cfg->cipher )
|
||||
, key( cfg->key )
|
||||
, macBytes( cfg->config->blockMACBytes )
|
||||
, randBytes( cfg->config->blockMACRandBytes )
|
||||
, macBytes( cfg->config->block_mac_bytes() )
|
||||
, randBytes( cfg->config->block_mac_rand_bytes() )
|
||||
, warnOnly( cfg->opts->forceDecode )
|
||||
{
|
||||
rAssert( macBytes >= 0 && macBytes <= 8 );
|
||||
rAssert( randBytes >= 0 );
|
||||
rLog(Info, "fs block size = %i, macBytes = %i, randBytes = %i",
|
||||
cfg->config->blockSize,
|
||||
cfg->config->blockMACBytes,
|
||||
cfg->config->blockMACRandBytes);
|
||||
cfg->config->block_size(),
|
||||
cfg->config->block_mac_bytes(),
|
||||
cfg->config->block_mac_rand_bytes());
|
||||
}
|
||||
|
||||
MACFileIO::~MACFileIO()
|
||||
{
|
||||
}
|
||||
|
||||
rel::Interface MACFileIO::interface() const
|
||||
Interface MACFileIO::interface() const
|
||||
{
|
||||
return MACFileIO_iface;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
MACFileIO();
|
||||
virtual ~MACFileIO();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
virtual void setFileName( const char *fileName );
|
||||
virtual const char *getFileName() const;
|
||||
|
@ -2,8 +2,10 @@
|
||||
include $(top_srcdir)/Makefile.common
|
||||
|
||||
ALL_INCLUDES = @RLOG_CFLAGS@ @OPENSSL_CFLAGS@ @BOOST_CPPFLAGS@
|
||||
ALL_INCLUDES += @PROTOBUF_CFLAGS@
|
||||
ALL_LDFLAGS = @RLOG_LIBS@ @OPENSSL_LIBS@ @BOOST_LDFLAGS@
|
||||
ALL_LDFLAGS += @BOOST_SERIALIZATION_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
|
||||
ALL_LDFLAGS += @BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
|
||||
ALL_LDFLAGS += @PROTOBUF_LIBS@
|
||||
|
||||
INCLUDES = $(all_includes) -I../intl
|
||||
|
||||
@ -47,10 +49,10 @@ endif
|
||||
# : : 0 => no new interfaces, but breaks old apps
|
||||
# : +1 : => internal changes, nothing breaks
|
||||
#
|
||||
libencfs_la_LDFLAGS = -version-info 6:2:0
|
||||
libencfs_la_LDFLAGS = -version-info 7:0:0
|
||||
libencfs_la_LIBADD = @RLOG_LIBS@ \
|
||||
@OPENSSL_LIBS@ \
|
||||
@BOOST_SERIALIZATION_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
|
||||
@BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
|
||||
|
||||
EXTRASRC = ../intl/autosprintf.cpp
|
||||
if BUILD_OPENSSL
|
||||
@ -62,6 +64,7 @@ endif
|
||||
libencfs_la_SOURCES = \
|
||||
readpassphrase.cpp \
|
||||
base64.cpp \
|
||||
config.pb.cc \
|
||||
ConfigReader.cpp \
|
||||
ConfigVar.cpp \
|
||||
Context.cpp \
|
||||
@ -83,6 +86,7 @@ libencfs_la_SOURCES = \
|
||||
FileNode.cpp \
|
||||
FileUtils.cpp \
|
||||
openssl.cpp \
|
||||
XmlReader.cpp \
|
||||
${EXTRASRC}
|
||||
|
||||
|
||||
@ -109,6 +113,7 @@ noinst_HEADERS = \
|
||||
CipherKey.h \
|
||||
ConfigReader.h \
|
||||
ConfigVar.h \
|
||||
config.pb.h \
|
||||
Context.h \
|
||||
DirNode.h \
|
||||
encfs.h \
|
||||
@ -134,8 +139,14 @@ noinst_HEADERS = \
|
||||
man_MANS=encfs.1 encfsctl.1
|
||||
EXTRA_DIST = encfs.pod encfsctl.pod encfs.1 encfsctl.1 encfs-man.html
|
||||
|
||||
SUFFIXES = .1 .pod .proto
|
||||
|
||||
config.pb.cc: config.pb.h
|
||||
|
||||
config.pb.h: config.proto
|
||||
@PROTOC@ --cpp_out=. config.proto
|
||||
|
||||
if BUILD_MAN
|
||||
SUFFIXES = .1 .pod
|
||||
# since we have POD2MAN, we can specify how to rebuild encfs.1 if necessary
|
||||
.pod.1:
|
||||
@POD2MAN@ --section=1 --release=@VERSION@ --center="Encrypted Filesystem" $< $@
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "config.h"
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||
#include <valgrind/memcheck.h>
|
||||
#else
|
||||
@ -34,6 +36,7 @@
|
||||
|
||||
using namespace rlog;
|
||||
|
||||
# include <openssl/crypto.h>
|
||||
# include <openssl/buffer.h>
|
||||
#define BLOCKDATA( BLOCK ) (unsigned char*)BLOCK->data->data
|
||||
|
||||
@ -140,4 +143,34 @@ void MemoryPool::destroyAll()
|
||||
}
|
||||
}
|
||||
|
||||
SecureMem::SecureMem(int len)
|
||||
{
|
||||
data = (char *)OPENSSL_malloc(len);
|
||||
if (data)
|
||||
{
|
||||
size = len;
|
||||
mlock(data, size);
|
||||
memset(data, '\0', size);
|
||||
VALGRIND_MAKE_MEM_UNDEFINED( data, size );
|
||||
} else
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SecureMem::~SecureMem()
|
||||
{
|
||||
if (size)
|
||||
{
|
||||
memset(data, '\0', size);
|
||||
munlock(data, size);
|
||||
|
||||
OPENSSL_free(data);
|
||||
VALGRIND_MAKE_MEM_NOACCESS( data, size );
|
||||
|
||||
data = NULL;
|
||||
size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,5 +50,14 @@ namespace MemoryPool
|
||||
void destroyAll();
|
||||
}
|
||||
|
||||
struct SecureMem
|
||||
{
|
||||
int size;
|
||||
char *data;
|
||||
|
||||
SecureMem(int len);
|
||||
~SecureMem();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "NullNameIO.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace rel;
|
||||
using namespace rlog;
|
||||
|
||||
#define REF_MODULE(TYPE) \
|
||||
@ -130,7 +129,7 @@ shared_ptr<NameIO> NameIO::New( const Interface &iface,
|
||||
NameIOMap_t::const_iterator end = gNameIOMap->end();
|
||||
for(it = gNameIOMap->begin(); it != end; ++it)
|
||||
{
|
||||
if( it->second.iface.implements( iface ))
|
||||
if( implements(it->second.iface, iface ))
|
||||
{
|
||||
Constructor fn = it->second.constructor;
|
||||
result = (*fn)( iface, cipher, key );
|
||||
|
@ -32,33 +32,33 @@ class Cipher;
|
||||
class NameIO
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<NameIO> (*Constructor)( const rel::Interface &iface,
|
||||
typedef shared_ptr<NameIO> (*Constructor)( const Interface &iface,
|
||||
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
||||
|
||||
struct Algorithm
|
||||
{
|
||||
std::string name;
|
||||
std::string description;
|
||||
rel::Interface iface;
|
||||
Interface iface;
|
||||
};
|
||||
|
||||
typedef std::list<Algorithm> AlgorithmList;
|
||||
static AlgorithmList GetAlgorithmList( bool includeHidden = false );
|
||||
|
||||
static shared_ptr<NameIO> New( const rel::Interface &iface,
|
||||
static shared_ptr<NameIO> New( const Interface &iface,
|
||||
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
||||
static shared_ptr<NameIO> New( const std::string &name,
|
||||
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
||||
|
||||
static bool Register( const char *name, const char *description,
|
||||
const rel::Interface &iface, Constructor constructor,
|
||||
const Interface &iface, Constructor constructor,
|
||||
bool hidden = false);
|
||||
|
||||
|
||||
NameIO();
|
||||
virtual ~NameIO();
|
||||
|
||||
virtual rel::Interface interface() const =0;
|
||||
virtual Interface interface() const =0;
|
||||
|
||||
void setChainedNameIV( bool enable );
|
||||
bool getChainedNameIV() const;
|
||||
|
@ -26,13 +26,12 @@
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
using namespace rel;
|
||||
using namespace rlog;
|
||||
using boost::shared_ptr;
|
||||
using boost::dynamic_pointer_cast;
|
||||
|
||||
|
||||
static Interface NullInterface( "nullCipher", 1, 0, 0 );
|
||||
static Interface NullInterface = makeInterface( "nullCipher", 1, 0, 0 );
|
||||
static Range NullKeyRange(0);
|
||||
static Range NullBlockRange(1,4096,1);
|
||||
|
||||
|
@ -28,13 +28,13 @@
|
||||
*/
|
||||
class NullCipher : public Cipher
|
||||
{
|
||||
rel::Interface iface;
|
||||
Interface iface;
|
||||
|
||||
public:
|
||||
NullCipher(const rel::Interface &iface);
|
||||
NullCipher(const Interface &iface);
|
||||
virtual ~NullCipher();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
// create a new key based on a password
|
||||
virtual CipherKey newKey(const char *password, int passwdLength,
|
||||
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace rel;
|
||||
using boost::shared_ptr;
|
||||
|
||||
static shared_ptr<NameIO> NewNNIO( const Interface &,
|
||||
@ -31,7 +30,7 @@ static shared_ptr<NameIO> NewNNIO( const Interface &,
|
||||
return shared_ptr<NameIO>( new NullNameIO() );
|
||||
}
|
||||
|
||||
static Interface NNIOIface("nameio/null", 1, 0, 0);
|
||||
static Interface NNIOIface = makeInterface("nameio/null", 1, 0, 0);
|
||||
static bool NullNameIO_registered = NameIO::Register("Null",
|
||||
"No encryption of filenames", NNIOIface, NewNNIO);
|
||||
|
||||
|
@ -23,13 +23,13 @@
|
||||
class NullNameIO : public NameIO
|
||||
{
|
||||
public:
|
||||
static rel::Interface CurrentInterface();
|
||||
static Interface CurrentInterface();
|
||||
|
||||
NullNameIO( );
|
||||
|
||||
virtual ~NullNameIO();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
||||
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
||||
|
@ -33,9 +33,9 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
static rel::Interface RawFileIO_iface("FileIO/Raw", 1, 0, 0);
|
||||
static Interface RawFileIO_iface = makeInterface("FileIO/Raw", 1, 0, 0);
|
||||
|
||||
FileIO *NewRawFileIO( const rel::Interface &iface )
|
||||
FileIO *NewRawFileIO( const Interface &iface )
|
||||
{
|
||||
(void)iface;
|
||||
return new RawFileIO();
|
||||
@ -82,7 +82,7 @@ RawFileIO::~RawFileIO()
|
||||
close( _fd );
|
||||
}
|
||||
|
||||
rel::Interface RawFileIO::interface() const
|
||||
Interface RawFileIO::interface() const
|
||||
{
|
||||
return RawFileIO_iface;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
RawFileIO( const std::string &fileName );
|
||||
virtual ~RawFileIO();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
virtual void setFileName( const char *fileName );
|
||||
virtual const char *getFileName() const;
|
||||
|
@ -66,10 +66,7 @@ inline int MIN(int a, int b)
|
||||
the state of EVP_CIPHER struct. EVP_BytesToKey will only produce 128 bit
|
||||
keys for the EVP Blowfish interface, which is not what we want.
|
||||
|
||||
Eliminated the salt code, since we don't use it.. Reason is that we're
|
||||
using the derived key to encode random data. Since there is no known
|
||||
plaintext, there is no ability for an attacker to pre-compute known
|
||||
password->data mappings, which is what the salt is meant to frustrate.
|
||||
DEPRECATED: this is here for backward compatibilty only. Use PBKDF
|
||||
*/
|
||||
int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
||||
const unsigned char *data, int dataLen,
|
||||
@ -103,7 +100,7 @@ int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
int toCopy = MIN( nkey, mds - offset );
|
||||
int toCopy = MIN( nkey, (int)mds - offset );
|
||||
if( toCopy )
|
||||
{
|
||||
memcpy( key, mdBuf+offset, toCopy );
|
||||
@ -111,7 +108,7 @@ int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
||||
nkey -= toCopy;
|
||||
offset += toCopy;
|
||||
}
|
||||
toCopy = MIN( niv, mds - offset );
|
||||
toCopy = MIN( niv, (int)mds - offset );
|
||||
if( toCopy )
|
||||
{
|
||||
memcpy( iv, mdBuf+offset, toCopy );
|
||||
@ -174,8 +171,8 @@ int TimedPBKDF2(const char *pass, int passlen,
|
||||
// - Version 2:1 adds support for Message Digest function interface
|
||||
// - Version 2:2 adds PBKDF2 for password derivation
|
||||
// - Version 3:0 adds a new IV mechanism
|
||||
static Interface BlowfishInterface( "ssl/blowfish", 3, 0, 2 );
|
||||
static Interface AESInterface( "ssl/aes", 3, 0, 2 );
|
||||
static Interface BlowfishInterface = makeInterface( "ssl/blowfish", 3, 0, 2 );
|
||||
static Interface AESInterface = makeInterface( "ssl/aes", 3, 0, 2 );
|
||||
|
||||
#if defined(HAVE_EVP_BF)
|
||||
|
||||
@ -275,19 +272,20 @@ SSLKey::SSLKey(int keySize_, int ivLength_)
|
||||
this->ivLength = ivLength_;
|
||||
pthread_mutex_init( &mutex, 0 );
|
||||
buffer = (unsigned char *)OPENSSL_malloc( keySize + ivLength );
|
||||
memset( buffer, 0, keySize + ivLength );
|
||||
|
||||
// most likely fails unless we're running as root, or a user-page-lock
|
||||
// kernel patch is applied..
|
||||
mlock( buffer, keySize + ivLength );
|
||||
|
||||
memset( buffer, 0, keySize + ivLength );
|
||||
}
|
||||
|
||||
SSLKey::~SSLKey()
|
||||
{
|
||||
memset( buffer, 0, keySize + ivLength );
|
||||
|
||||
OPENSSL_free( buffer );
|
||||
munlock( buffer, keySize + ivLength );
|
||||
OPENSSL_free( buffer );
|
||||
|
||||
keySize = 0;
|
||||
ivLength = 0;
|
||||
@ -370,7 +368,7 @@ SSL_Cipher::SSL_Cipher(const Interface &iface_,
|
||||
iface.name().c_str(), _keySize, _ivLength);
|
||||
|
||||
if( (EVP_CIPHER_key_length( _blockCipher ) != (int )_keySize)
|
||||
&& iface.current() == 1)
|
||||
&& iface.major() == 1)
|
||||
{
|
||||
rWarning("Running in backward compatibilty mode for 1.0 - \n"
|
||||
"key is really %i bits, not %i.\n"
|
||||
@ -438,7 +436,7 @@ CipherKey SSL_Cipher::newKey(const char *password, int passwdLength)
|
||||
shared_ptr<SSLKey> key( new SSLKey( _keySize, _ivLength) );
|
||||
|
||||
int bytes = 0;
|
||||
if( iface.current() > 1 )
|
||||
if( iface.major() > 1 )
|
||||
{
|
||||
// now we use BytesToKey, which can deal with Blowfish keys larger then
|
||||
// 128 bits.
|
||||
@ -680,7 +678,7 @@ int SSL_Cipher::cipherBlockSize() const
|
||||
void SSL_Cipher::setIVec( unsigned char *ivec, uint64_t seed,
|
||||
const shared_ptr<SSLKey> &key) const
|
||||
{
|
||||
if (iface.current() >= 3)
|
||||
if (iface.major() >= 3)
|
||||
{
|
||||
memcpy( ivec, IVData(key), _ivLength );
|
||||
|
||||
@ -707,7 +705,7 @@ void SSL_Cipher::setIVec( unsigned char *ivec, uint64_t seed,
|
||||
}
|
||||
}
|
||||
|
||||
/** For backward compatibility.
|
||||
/** Deprecated: For backward compatibility only.
|
||||
A watermark attack was discovered against this IV setup. If an attacker
|
||||
could get a victim to store a carefully crafted file, they could later
|
||||
determine if the victim had the file in encrypted storage (without
|
||||
@ -717,13 +715,6 @@ void SSL_Cipher::setIVec_old(unsigned char *ivec,
|
||||
unsigned int seed,
|
||||
const shared_ptr<SSLKey> &key) const
|
||||
{
|
||||
/* These multiplication constants chosen as they represent (non optimal)
|
||||
Golumb rulers, the idea being to spread around the information in the
|
||||
seed.
|
||||
|
||||
0x060a4011 : ruler length 26, 7 marks, 21 measurable lengths
|
||||
0x0221040d : ruler length 25, 7 marks, 21 measurable lengths
|
||||
*/
|
||||
unsigned int var1 = 0x060a4011 * seed;
|
||||
unsigned int var2 = 0x0221040d * (seed ^ 0xD3FEA11C);
|
||||
|
||||
|
@ -70,21 +70,21 @@ using boost::shared_ptr;
|
||||
*/
|
||||
class SSL_Cipher : public Cipher
|
||||
{
|
||||
rel::Interface iface;
|
||||
rel::Interface realIface;
|
||||
Interface iface;
|
||||
Interface realIface;
|
||||
const EVP_CIPHER *_blockCipher;
|
||||
const EVP_CIPHER *_streamCipher;
|
||||
unsigned int _keySize; // in bytes
|
||||
unsigned int _ivLength;
|
||||
|
||||
public:
|
||||
SSL_Cipher(const rel::Interface &iface, const rel::Interface &realIface,
|
||||
SSL_Cipher(const Interface &iface, const Interface &realIface,
|
||||
const EVP_CIPHER *blockCipher, const EVP_CIPHER *streamCipher,
|
||||
int keyLength);
|
||||
virtual ~SSL_Cipher();
|
||||
|
||||
// returns the real interface, not the one we're emulating (if any)..
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
// create a new key based on a password
|
||||
virtual CipherKey newKey(const char *password, int passwdLength,
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "i18n.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace rel;
|
||||
using namespace std;
|
||||
|
||||
static shared_ptr<NameIO> NewStreamNameIO( const Interface &iface,
|
||||
@ -65,13 +64,13 @@ static bool StreamIO_registered = NameIO::Register("Stream",
|
||||
Interface StreamNameIO::CurrentInterface()
|
||||
{
|
||||
// implement major version 2, 1, and 0
|
||||
return Interface("nameio/stream", 2, 1, 2);
|
||||
return makeInterface("nameio/stream", 2, 1, 2);
|
||||
}
|
||||
|
||||
StreamNameIO::StreamNameIO( const rel::Interface &iface,
|
||||
StreamNameIO::StreamNameIO( const Interface &iface,
|
||||
const shared_ptr<Cipher> &cipher,
|
||||
const CipherKey &key )
|
||||
: _interface( iface.current() )
|
||||
: _interface( iface.major() )
|
||||
, _cipher( cipher )
|
||||
, _key( key )
|
||||
{
|
||||
|
@ -27,14 +27,14 @@ using boost::shared_ptr;
|
||||
class StreamNameIO : public NameIO
|
||||
{
|
||||
public:
|
||||
static rel::Interface CurrentInterface();
|
||||
static Interface CurrentInterface();
|
||||
|
||||
StreamNameIO( const rel::Interface &iface,
|
||||
StreamNameIO( const Interface &iface,
|
||||
const shared_ptr<Cipher> &cipher,
|
||||
const CipherKey &key );
|
||||
virtual ~StreamNameIO();
|
||||
|
||||
virtual rel::Interface interface() const;
|
||||
virtual Interface interface() const;
|
||||
|
||||
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
||||
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
||||
|
191
encfs/XmlReader.cpp
Normal file
191
encfs/XmlReader.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
/*****************************************************************************
|
||||
* 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 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 General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "XmlReader.h"
|
||||
#include "base64.h"
|
||||
|
||||
#include <rlog/rlog.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <tinyxml.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace rlog;
|
||||
|
||||
XmlValue::~XmlValue()
|
||||
{
|
||||
}
|
||||
|
||||
XmlValuePtr XmlValue::operator[] (const char *path) const
|
||||
{
|
||||
return this->find(path);
|
||||
}
|
||||
|
||||
XmlValuePtr XmlValue::find(const char *name) const
|
||||
{
|
||||
rError("in XmlValue::operator[%s]", name);
|
||||
return XmlValuePtr(new XmlValue());
|
||||
}
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, std::string &out)
|
||||
{
|
||||
out = ptr->text();
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, int &out)
|
||||
{
|
||||
out = atoi(ptr->text().c_str());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, long &out)
|
||||
{
|
||||
out = atol(ptr->text().c_str());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, double &out)
|
||||
{
|
||||
out = atof(ptr->text().c_str());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, bool &out)
|
||||
{
|
||||
out = atoi(ptr->text().c_str());
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool XmlValue::readB64Data(unsigned char *data, int length) const
|
||||
{
|
||||
std::string s = value;
|
||||
s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end());
|
||||
|
||||
BIO *b64 = BIO_new(BIO_f_base64());
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
|
||||
BIO *bmem = BIO_new_mem_buf((void *)s.c_str(), s.size());
|
||||
bmem = BIO_push(b64, bmem);
|
||||
|
||||
int decodedSize = BIO_read(bmem, data, length);
|
||||
BIO_free_all(b64);
|
||||
|
||||
if (decodedSize != length)
|
||||
{
|
||||
rError("decoding bytes len %i, expecting output len %i, got %i",
|
||||
(int)s.size(), length, decodedSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string safeValueForNode(TiXmlElement *element)
|
||||
{
|
||||
std::string value;
|
||||
const TiXmlNode *child = element->FirstChild();
|
||||
if (child)
|
||||
{
|
||||
const TiXmlText *childText = child->ToText();
|
||||
if (childText)
|
||||
value = childText->Value();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
class XmlNode : virtual public XmlValue
|
||||
{
|
||||
TiXmlElement *element;
|
||||
public:
|
||||
XmlNode(TiXmlElement *element_)
|
||||
: XmlValue(safeValueForNode(element_))
|
||||
, element(element_)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~XmlNode()
|
||||
{
|
||||
}
|
||||
|
||||
virtual XmlValuePtr find(const char *name) const
|
||||
{
|
||||
if (name[0] == '@')
|
||||
{
|
||||
return XmlValuePtr(new XmlValue(element->Attribute(name+1)));
|
||||
} else
|
||||
{
|
||||
return XmlValuePtr(new XmlNode(element->FirstChild(name)->ToElement()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct XmlReader::XmlReaderData
|
||||
{
|
||||
boost::shared_ptr<TiXmlDocument> doc;
|
||||
};
|
||||
|
||||
XmlReader::XmlReader()
|
||||
: pd(new XmlReaderData())
|
||||
{
|
||||
}
|
||||
|
||||
XmlReader::~XmlReader()
|
||||
{
|
||||
}
|
||||
|
||||
bool XmlReader::load(const char *fileName)
|
||||
{
|
||||
pd->doc.reset(new TiXmlDocument(fileName));
|
||||
|
||||
return pd->doc->LoadFile();
|
||||
}
|
||||
|
||||
XmlValuePtr XmlReader::operator[] ( const char *name ) const
|
||||
{
|
||||
TiXmlNode *node = pd->doc->FirstChild(name);
|
||||
if (node == NULL)
|
||||
{
|
||||
rError("Xml node %s not found", name);
|
||||
return XmlValuePtr(new XmlValue());
|
||||
}
|
||||
|
||||
TiXmlElement *element = node->ToElement();
|
||||
if (element == NULL)
|
||||
{
|
||||
rError("Xml node %s not element, type = %i", name, node->Type());
|
||||
return XmlValuePtr(new XmlValue());
|
||||
}
|
||||
|
||||
return XmlValuePtr(new XmlNode(element));
|
||||
}
|
||||
|
78
encfs/XmlReader.h
Normal file
78
encfs/XmlReader.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* 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 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 General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _XmlReader_incl_
|
||||
#define _XmlReader_incl_
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <string>
|
||||
|
||||
class XmlValue;
|
||||
typedef boost::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;
|
||||
|
||||
bool readB64Data(unsigned char *data, int length) const;
|
||||
|
||||
const std::string &text() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual XmlValuePtr find(const char *name) const;
|
||||
};
|
||||
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, std::string &outStr);
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, int &out);
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, long &out);
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, double &out);
|
||||
const XmlValuePtr & operator >> (const XmlValuePtr &ptr, bool &out);
|
||||
|
||||
class XmlReader
|
||||
{
|
||||
public:
|
||||
XmlReader();
|
||||
~XmlReader();
|
||||
|
||||
bool load(const char *fileName);
|
||||
|
||||
XmlValuePtr operator[](const char *name) const;
|
||||
|
||||
private:
|
||||
struct XmlReaderData;
|
||||
boost::shared_ptr<XmlReaderData> pd;
|
||||
};
|
||||
|
||||
#endif
|
36
encfs/config.proto
Normal file
36
encfs/config.proto
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
message EncfsConfig
|
||||
{
|
||||
optional string creator = 1;
|
||||
optional int32 revision = 2 [default=0];
|
||||
|
||||
required Interface cipher = 3;
|
||||
required bytes key = 4;
|
||||
optional bytes salt = 41;
|
||||
required int32 key_size = 42; // in bits
|
||||
optional int32 kdf_iterations = 43 [default=0];
|
||||
optional int32 kdf_duration = 44 [default=500];
|
||||
|
||||
optional Interface naming = 5;
|
||||
optional bool unique_iv = 51 [default=false];
|
||||
optional bool chained_iv = 52 [default=false];
|
||||
optional bool external_iv = 53 [default=false];
|
||||
|
||||
required int32 block_size = 6;
|
||||
optional int32 block_mac_bytes = 61 [default=0];
|
||||
optional int32 block_mac_rand_bytes = 611 [default=0];
|
||||
optional bool allow_holes = 62 [default = false];
|
||||
}
|
||||
|
||||
message Interface
|
||||
{
|
||||
required string name = 1;
|
||||
required uint32 major = 2; // major version number
|
||||
required uint32 minor = 3; // minor version number
|
||||
|
||||
// Age indicates number of major versions supported. 0 means no backward
|
||||
// compatibility. See libtool "updating version information" for more
|
||||
// details on how major/minor/age are used for versioning libraries.
|
||||
optional uint32 age = 4;
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ static int showInfo( int argc, char **argv )
|
||||
if( !checkDir( rootDir ))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
|
||||
EncfsConfig config;
|
||||
ConfigType type = readConfig( rootDir, config );
|
||||
|
||||
// show information stored in config..
|
||||
@ -194,24 +194,22 @@ static int showInfo( int argc, char **argv )
|
||||
case Config_V3:
|
||||
// xgroup(diag)
|
||||
cout << "\n" << autosprintf(_("Version 3 configuration; "
|
||||
"created by %s\n"), config->creator.c_str());
|
||||
"created by %s\n"), config.creator().c_str());
|
||||
break;
|
||||
case Config_V4:
|
||||
// xgroup(diag)
|
||||
cout << "\n" << autosprintf(_("Version 4 configuration; "
|
||||
"created by %s\n"), config->creator.c_str());
|
||||
"created by %s\n"), config.creator().c_str());
|
||||
break;
|
||||
case Config_V5:
|
||||
// xgroup(diag)
|
||||
cout << "\n" << autosprintf(_("Version 5 configuration; "
|
||||
"created by %s (revision %i)\n"), config->creator.c_str(),
|
||||
config->subVersion);
|
||||
break;
|
||||
case Config_V6:
|
||||
case Config_V7:
|
||||
// xgroup(diag)
|
||||
cout << "\n" << autosprintf(_("Version 6 configuration; "
|
||||
"created by %s (revision %i)\n"), config->creator.c_str(),
|
||||
config->subVersion);
|
||||
cout << "\n" << autosprintf(_("Version %i configuration; "
|
||||
"created by %s (revision %i)\n"),
|
||||
type,
|
||||
config.creator().c_str(),
|
||||
config.revision());
|
||||
break;
|
||||
}
|
||||
|
||||
@ -687,9 +685,7 @@ static int cmd_showcruft( int argc, char **argv )
|
||||
|
||||
int filesFound = showcruft( rootInfo, "/" );
|
||||
|
||||
cerr << autosprintf(
|
||||
ngettext("Found %i invalid file.", "Found %i invalid files.",
|
||||
filesFound), filesFound) << "\n";
|
||||
cerr << autosprintf("Found %i invalid file(s).", filesFound) << "\n";
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@ -701,7 +697,7 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
||||
if( !checkDir( rootDir ))
|
||||
return EXIT_FAILURE;
|
||||
|
||||
boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
|
||||
EncfsConfig config;
|
||||
ConfigType cfgType = readConfig( rootDir, config );
|
||||
|
||||
if(cfgType == Config_None)
|
||||
@ -711,12 +707,11 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
||||
}
|
||||
|
||||
// instanciate proper cipher
|
||||
shared_ptr<Cipher> cipher = Cipher::New(
|
||||
config->cipherIface, config->keySize );
|
||||
shared_ptr<Cipher> cipher = getCipher(config);
|
||||
if(!cipher)
|
||||
{
|
||||
cout << autosprintf(_("Unable to find specified cipher \"%s\"\n"),
|
||||
config->cipherIface.name().c_str());
|
||||
config.cipher().name().c_str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@ -724,13 +719,14 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
||||
cout << _("Enter current Encfs password\n");
|
||||
if (annotate)
|
||||
cerr << "$PROMPT$ passwd" << endl;
|
||||
CipherKey userKey = config->getUserKey( useStdin );
|
||||
CipherKey userKey = getUserKey( config, useStdin );
|
||||
if(!userKey)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// decode volume key using user key -- at this point we detect an incorrect
|
||||
// password if the key checksum does not match (causing readKey to fail).
|
||||
CipherKey volumeKey = cipher->readKey( config->getKeyData(), userKey );
|
||||
CipherKey volumeKey = cipher->readKey(
|
||||
(const unsigned char *)config.key().data(), userKey );
|
||||
|
||||
if(!volumeKey)
|
||||
{
|
||||
@ -741,17 +737,15 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
||||
// Now, get New user key..
|
||||
userKey.reset();
|
||||
cout << _("Enter new Encfs password\n");
|
||||
// reinitialize salt and iteration count
|
||||
config->kdfIterations = 0; // generate new
|
||||
|
||||
// create new key
|
||||
if( useStdin )
|
||||
{
|
||||
if (annotate)
|
||||
cerr << "$PROMPT$ new_passwd" << endl;
|
||||
userKey = config->getUserKey( true );
|
||||
}
|
||||
else
|
||||
userKey = config->getNewUserKey();
|
||||
|
||||
userKey = getNewUserKey( config, useStdin, string(), string() );
|
||||
|
||||
// re-encode the volume key using the new user key and write it out..
|
||||
int result = EXIT_FAILURE;
|
||||
@ -764,10 +758,10 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
||||
cipher->writeKey( volumeKey, keyBuf, userKey );
|
||||
userKey.reset();
|
||||
|
||||
config->assignKeyData( keyBuf, encodedKeySize );
|
||||
config.set_key( keyBuf, encodedKeySize );
|
||||
delete[] keyBuf;
|
||||
|
||||
if(saveConfig( cfgType, rootDir, config ))
|
||||
if(saveConfig( rootDir, config ))
|
||||
{
|
||||
// password modified -- changes volume key of filesystem..
|
||||
cout << _("Volume Key successfully updated.\n");
|
||||
@ -816,7 +810,7 @@ int main(int argc, char **argv)
|
||||
slog->subscribeTo( GetGlobalChannel("error") );
|
||||
slog->subscribeTo( GetGlobalChannel("warning") );
|
||||
#ifndef NO_DEBUG
|
||||
//slog->subscribeTo( GetGlobalChannel("debug") );
|
||||
slog->subscribeTo( GetGlobalChannel("debug") );
|
||||
#endif
|
||||
|
||||
if(argc < 2)
|
||||
|
@ -69,7 +69,6 @@ inline static int MAX(int a, int b)
|
||||
|
||||
using namespace std;
|
||||
using namespace rlog;
|
||||
using namespace rel;
|
||||
using namespace gnu;
|
||||
using boost::shared_ptr;
|
||||
using boost::scoped_ptr;
|
||||
|
@ -47,11 +47,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/text_format.h>
|
||||
|
||||
#include <tr1/unordered_set>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace rel;
|
||||
using namespace rlog;
|
||||
|
||||
using boost::shared_ptr;
|
||||
@ -235,35 +236,28 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
||||
cipher->writeKey( key, keyBuf, encodingKey );
|
||||
|
||||
// store in config struct..
|
||||
EncFSConfig cfg;
|
||||
cfg.cipherIface = cipher->interface();
|
||||
cfg.keySize = 8 * cipher->keySize();
|
||||
cfg.blockSize = FSBlockSize;
|
||||
cfg.assignKeyData( keyBuf, encodedKeySize );
|
||||
EncfsConfig cfg;
|
||||
cfg.mutable_cipher()->MergeFrom(cipher->interface());
|
||||
cfg.set_key_size(8 * cipher->keySize());
|
||||
cfg.set_block_size(FSBlockSize);
|
||||
cfg.set_key( keyBuf, encodedKeySize );
|
||||
|
||||
// save config
|
||||
string data;
|
||||
{
|
||||
ostringstream st;
|
||||
st << cfg;
|
||||
data = st.str();
|
||||
}
|
||||
google::protobuf::TextFormat::PrintToString(cfg, &data);
|
||||
|
||||
// read back in and check everything..
|
||||
EncFSConfig cfg2;
|
||||
{
|
||||
istringstream st(data);
|
||||
st >> cfg2;
|
||||
}
|
||||
EncfsConfig cfg2;
|
||||
google::protobuf::TextFormat::ParseFromString(data, &cfg2);
|
||||
|
||||
// check..
|
||||
rAssert( cfg.cipherIface.implements(cfg2.cipherIface) );
|
||||
rAssert( cfg.keySize == cfg2.keySize );
|
||||
rAssert( cfg.blockSize == cfg2.blockSize );
|
||||
rAssert( implements(cfg.cipher(),cfg2.cipher()) );
|
||||
rAssert( cfg.key_size() == cfg2.key_size() );
|
||||
rAssert( cfg.block_size() == cfg2.block_size() );
|
||||
|
||||
// try decoding key..
|
||||
|
||||
CipherKey key2 = cipher->readKey( cfg2.getKeyData(), encodingKey );
|
||||
CipherKey key2 = cipher->readKey( (unsigned char *)cfg2.key().data(), encodingKey );
|
||||
if(!key2)
|
||||
{
|
||||
if(verbose)
|
||||
@ -286,15 +280,15 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
||||
FSConfigPtr fsCfg = FSConfigPtr(new FSConfig);
|
||||
fsCfg->cipher = cipher;
|
||||
fsCfg->key = key;
|
||||
fsCfg->config.reset(new EncFSConfig);
|
||||
fsCfg->config->blockSize = FSBlockSize;
|
||||
fsCfg->config.reset(new EncfsConfig);
|
||||
fsCfg->config->set_block_size(FSBlockSize);
|
||||
|
||||
if(verbose)
|
||||
cerr << "Testing name encode/decode (stream coding w/ IV chaining)\n";
|
||||
{
|
||||
fsCfg->opts.reset(new EncFS_Opts);
|
||||
fsCfg->opts->idleTracking = false;
|
||||
fsCfg->config->uniqueIV = false;
|
||||
fsCfg->config->set_unique_iv(false);
|
||||
|
||||
fsCfg->nameCoding.reset( new StreamNameIO(
|
||||
StreamNameIO::CurrentInterface(), cipher, key ) );
|
||||
@ -310,7 +304,7 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
||||
cerr << "Testing name encode/decode (block coding w/ IV chaining)\n";
|
||||
{
|
||||
fsCfg->opts->idleTracking = false;
|
||||
fsCfg->config->uniqueIV = false;
|
||||
fsCfg->config->set_unique_iv(false);
|
||||
fsCfg->nameCoding.reset( new BlockNameIO(
|
||||
BlockNameIO::CurrentInterface(), cipher, key,
|
||||
cipher->cipherBlockSize() ) );
|
||||
@ -326,7 +320,7 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
||||
cerr << "Testing name encode/decode (block coding w/ IV chaining, base32)\n";
|
||||
{
|
||||
fsCfg->opts->idleTracking = false;
|
||||
fsCfg->config->uniqueIV = false;
|
||||
fsCfg->config->set_unique_iv(false);
|
||||
fsCfg->nameCoding.reset( new BlockNameIO(
|
||||
BlockNameIO::CurrentInterface(), cipher, key,
|
||||
cipher->cipherBlockSize(), true ) );
|
||||
@ -503,8 +497,8 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
cerr << it->name
|
||||
<< " ( " << it->iface.name() << " "
|
||||
<< it->iface.current() << ":"
|
||||
<< it->iface.revision() << ":"
|
||||
<< it->iface.major() << ":"
|
||||
<< it->iface.minor() << ":"
|
||||
<< it->iface.age() << " ) : " << it->description << "\n";
|
||||
cerr << " - key length " << it->keyLength.min() << " to "
|
||||
<< it->keyLength.max() << " , block size " << it->blockSize.min()
|
||||
|
Loading…
Reference in New Issue
Block a user