mirror of
https://github.com/vgough/encfs.git
synced 2024-11-22 16:03:34 +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>
|
Wed Dec 28 2011 Valient Gough <vgough@pobox.com>
|
||||||
* remove m4-local
|
* remove m4-local
|
||||||
* bump version to 1.7.5
|
* 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_INIT(encfs/encfs.h) dnl a source file from your sub dir
|
||||||
AC_CONFIG_AUX_DIR([build-aux])
|
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_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
@ -48,7 +48,6 @@ AX_PTHREAD
|
|||||||
|
|
||||||
AX_BOOST_BASE([1.34])
|
AX_BOOST_BASE([1.34])
|
||||||
AX_BOOST_SYSTEM
|
AX_BOOST_SYSTEM
|
||||||
AX_BOOST_SERIALIZATION
|
|
||||||
AX_BOOST_FILESYSTEM
|
AX_BOOST_FILESYSTEM
|
||||||
|
|
||||||
dnl Need to include any user specified flags in the tests below, as they might
|
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])])
|
[AC_MSG_ERROR([EncFS depends on librlog])])
|
||||||
fi
|
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
|
# look for pod2man program for building man pages
|
||||||
AC_PATH_PROG(POD2MAN, pod2man, [no])
|
AC_PATH_PROG(POD2MAN, pod2man, [no])
|
||||||
AC_PATH_PROG(POD2HTML, pod2html, [no])
|
AC_PATH_PROG(POD2HTML, pod2html, [no])
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "BlockFileIO.h"
|
#include "BlockFileIO.h"
|
||||||
|
|
||||||
#include "MemoryPool.h"
|
#include "MemoryPool.h"
|
||||||
|
#include "config.pb.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <rlog/rlog.h>
|
#include <rlog/rlog.h>
|
||||||
@ -38,7 +39,7 @@ static void clearCache( IORequest &req, int blockSize )
|
|||||||
|
|
||||||
BlockFileIO::BlockFileIO( int blockSize, const FSConfigPtr &cfg )
|
BlockFileIO::BlockFileIO( int blockSize, const FSConfigPtr &cfg )
|
||||||
: _blockSize( blockSize )
|
: _blockSize( blockSize )
|
||||||
, _allowHoles( cfg->config->allowHoles )
|
, _allowHoles( cfg->config->allow_holes() )
|
||||||
{
|
{
|
||||||
rAssert( _blockSize > 1 );
|
rAssert( _blockSize > 1 );
|
||||||
_cache.data = new unsigned char [ _blockSize ];
|
_cache.data = new unsigned char [ _blockSize ];
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
using namespace rel;
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
static RLogChannel * Info = DEF_CHANNEL( "info/nameio", Log_Info );
|
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
|
// implement major version 4 plus support for two prior versions
|
||||||
if (caseSensitive)
|
if (caseSensitive)
|
||||||
return Interface("nameio/block32", 4, 0, 2);
|
return makeInterface("nameio/block32", 4, 0, 2);
|
||||||
else
|
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 shared_ptr<Cipher> &cipher,
|
||||||
const CipherKey &key, int blockSize,
|
const CipherKey &key, int blockSize,
|
||||||
bool caseSensitiveEncoding )
|
bool caseSensitiveEncoding )
|
||||||
: _interface( iface.current() )
|
: _interface( iface.major() )
|
||||||
, _bs( blockSize )
|
, _bs( blockSize )
|
||||||
, _cipher( cipher )
|
, _cipher( cipher )
|
||||||
, _key( key )
|
, _key( key )
|
||||||
|
@ -33,15 +33,15 @@ class Cipher;
|
|||||||
class BlockNameIO : public NameIO
|
class BlockNameIO : public NameIO
|
||||||
{
|
{
|
||||||
public:
|
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 boost::shared_ptr<Cipher> &cipher,
|
||||||
const CipherKey &key, int blockSize,
|
const CipherKey &key, int blockSize,
|
||||||
bool caseSensitiveEncoding = false );
|
bool caseSensitiveEncoding = false );
|
||||||
virtual ~BlockNameIO();
|
virtual ~BlockNameIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
||||||
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "SSL_Cipher.h"
|
#include "SSL_Cipher.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rel;
|
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
|
|
||||||
#define REF_MODULE(TYPE) \
|
#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)
|
for(it = gCipherMap->begin(); it != mapEnd; ++it)
|
||||||
{
|
{
|
||||||
// TODO: we should look for the newest implementation..
|
// 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;
|
CipherConstructor fn = it->second.constructor;
|
||||||
// pass in requested interface..
|
// pass in requested interface..
|
||||||
|
@ -42,14 +42,14 @@ class Cipher
|
|||||||
public:
|
public:
|
||||||
// if no key length was indicated when cipher was registered, then keyLen
|
// if no key length was indicated when cipher was registered, then keyLen
|
||||||
// <= 0 will be used.
|
// <= 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 );
|
int keyLenBits );
|
||||||
|
|
||||||
struct CipherAlgorithm
|
struct CipherAlgorithm
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
rel::Interface iface;
|
Interface iface;
|
||||||
Range keyLength;
|
Range keyLength;
|
||||||
Range blockSize;
|
Range blockSize;
|
||||||
};
|
};
|
||||||
@ -59,7 +59,7 @@ public:
|
|||||||
static AlgorithmList GetAlgorithmList( bool includeHidden = false );
|
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);
|
int keyLen = -1);
|
||||||
static boost::shared_ptr<Cipher> New( const std::string &cipherName,
|
static boost::shared_ptr<Cipher> New( const std::string &cipherName,
|
||||||
int keyLen = -1 );
|
int keyLen = -1 );
|
||||||
@ -67,12 +67,12 @@ public:
|
|||||||
|
|
||||||
static bool Register(const char *cipherName,
|
static bool Register(const char *cipherName,
|
||||||
const char *description,
|
const char *description,
|
||||||
const rel::Interface &iface,
|
const Interface &iface,
|
||||||
CipherConstructor constructor,
|
CipherConstructor constructor,
|
||||||
bool hidden = false);
|
bool hidden = false);
|
||||||
static bool Register(const char *cipherName,
|
static bool Register(const char *cipherName,
|
||||||
const char *description,
|
const char *description,
|
||||||
const rel::Interface &iface,
|
const Interface &iface,
|
||||||
const Range &keyLength, const Range &blockSize,
|
const Range &keyLength, const Range &blockSize,
|
||||||
CipherConstructor constructor,
|
CipherConstructor constructor,
|
||||||
bool hidden = false);
|
bool hidden = false);
|
||||||
@ -81,7 +81,7 @@ public:
|
|||||||
Cipher();
|
Cipher();
|
||||||
virtual ~Cipher();
|
virtual ~Cipher();
|
||||||
|
|
||||||
virtual rel::Interface interface() const =0;
|
virtual Interface interface() const =0;
|
||||||
|
|
||||||
// create a new key based on a password
|
// create a new key based on a password
|
||||||
// if iterationCount == 0, then iteration count will be determined
|
// if iterationCount == 0, then iteration count will be determined
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "Cipher.h"
|
#include "Cipher.h"
|
||||||
#include "MemoryPool.h"
|
#include "MemoryPool.h"
|
||||||
|
#include "config.pb.h"
|
||||||
|
|
||||||
#include <rlog/rlog.h>
|
#include <rlog/rlog.h>
|
||||||
#include <rlog/Error.h>
|
#include <rlog/Error.h>
|
||||||
@ -34,7 +35,7 @@ using boost::shared_ptr;
|
|||||||
filesystem at the filesystem configuration level.
|
filesystem at the filesystem configuration level.
|
||||||
When headers are disabled, 2:0 is compatible with version 1:0.
|
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..
|
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,
|
CipherFileIO::CipherFileIO( const shared_ptr<FileIO> &_base,
|
||||||
const FSConfigPtr &cfg)
|
const FSConfigPtr &cfg)
|
||||||
: BlockFileIO( cfg->config->blockSize, cfg )
|
: BlockFileIO( cfg->config->block_size(), cfg )
|
||||||
, base( _base )
|
, base( _base )
|
||||||
, haveHeader( cfg->config->uniqueIV )
|
, haveHeader( cfg->config->unique_iv() )
|
||||||
, externalIV( 0 )
|
, externalIV( 0 )
|
||||||
, fileIV( 0 )
|
, fileIV( 0 )
|
||||||
, lastFlags( 0 )
|
, lastFlags( 0 )
|
||||||
@ -65,7 +66,7 @@ CipherFileIO::CipherFileIO( const shared_ptr<FileIO> &_base,
|
|||||||
static bool warnOnce = false;
|
static bool warnOnce = false;
|
||||||
|
|
||||||
if(!warnOnce)
|
if(!warnOnce)
|
||||||
warnOnce = checkSize( fsConfig->config->blockSize,
|
warnOnce = checkSize( fsConfig->config->block_size(),
|
||||||
fsConfig->cipher->cipherBlockSize() );
|
fsConfig->cipher->cipherBlockSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ CipherFileIO::~CipherFileIO()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
rel::Interface CipherFileIO::interface() const
|
Interface CipherFileIO::interface() const
|
||||||
{
|
{
|
||||||
return CipherFileIO_iface;
|
return CipherFileIO_iface;
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
const FSConfigPtr &cfg);
|
const FSConfigPtr &cfg);
|
||||||
virtual ~CipherFileIO();
|
virtual ~CipherFileIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
virtual void setFileName( const char *fileName );
|
virtual void setFileName( const char *fileName );
|
||||||
virtual const char *getFileName() const;
|
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());
|
rLog(Info, "link %s -> %s", fromCName.c_str(), toCName.c_str());
|
||||||
|
|
||||||
int res = -EPERM;
|
int res = -EPERM;
|
||||||
if( fsConfig->config->externalIVChaining )
|
if( fsConfig->config->external_iv() )
|
||||||
{
|
{
|
||||||
rLog(Info, "hard links not supported with external IV chaining!");
|
rLog(Info, "hard links not supported with external IV chaining!");
|
||||||
} else
|
} else
|
||||||
@ -756,7 +756,7 @@ shared_ptr<FileNode> DirNode::findOrCreate( const char *plainName)
|
|||||||
plainName,
|
plainName,
|
||||||
(rootDir + cipherName).c_str()));
|
(rootDir + cipherName).c_str()));
|
||||||
|
|
||||||
if(fsConfig->config->externalIVChaining)
|
if(fsConfig->config->external_iv())
|
||||||
node->setName(0, 0, iv);
|
node->setName(0, 0, iv);
|
||||||
|
|
||||||
rLog(Info, "created FileNode for %s", node->cipherName());
|
rLog(Info, "created FileNode for %s", node->cipherName());
|
||||||
|
@ -32,88 +32,37 @@ enum ConfigType
|
|||||||
{
|
{
|
||||||
Config_None = 0,
|
Config_None = 0,
|
||||||
Config_Prehistoric,
|
Config_Prehistoric,
|
||||||
Config_V3,
|
Config_V3 = 3,
|
||||||
Config_V4,
|
Config_V4 = 4,
|
||||||
Config_V5,
|
Config_V5 = 5,
|
||||||
Config_V6
|
Config_V6 = 6,
|
||||||
|
Config_V7 = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
class EncFS_Opts;
|
class EncFS_Opts;
|
||||||
class Cipher;
|
class Cipher;
|
||||||
class NameIO;
|
class NameIO;
|
||||||
|
class EncfsConfig;
|
||||||
|
|
||||||
struct EncFSConfig
|
CipherKey getUserKey(const EncfsConfig &config, bool useStdin);
|
||||||
{
|
CipherKey getUserKey(const EncfsConfig &config,
|
||||||
ConfigType cfgType;
|
const std::string &passwordProgram,
|
||||||
|
|
||||||
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);
|
const std::string &rootDir);
|
||||||
CipherKey getNewUserKey();
|
|
||||||
|
|
||||||
boost::shared_ptr<Cipher> getCipher() const;
|
CipherKey getNewUserKey(EncfsConfig &config, bool useStdin,
|
||||||
|
const std::string &program, const std::string &rootDir);
|
||||||
|
|
||||||
// deprecated
|
boost::shared_ptr<Cipher> getCipher(const EncfsConfig &cfg);
|
||||||
void assignKeyData(const std::string &in);
|
boost::shared_ptr<Cipher> getCipher(const Interface &iface, int keySize);
|
||||||
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
|
// helpers for serializing to/from a stream
|
||||||
std::ostream &operator << (std::ostream &os, const EncFSConfig &cfg);
|
std::ostream &operator << (std::ostream &os, const EncfsConfig &cfg);
|
||||||
std::istream &operator >> (std::istream &os, EncFSConfig &cfg);
|
std::istream &operator >> (std::istream &os, EncfsConfig &cfg);
|
||||||
|
|
||||||
|
// Filesystem state
|
||||||
struct FSConfig
|
struct FSConfig
|
||||||
{
|
{
|
||||||
boost::shared_ptr<EncFSConfig> config;
|
boost::shared_ptr<EncfsConfig> config;
|
||||||
boost::shared_ptr<EncFS_Opts> opts;
|
boost::shared_ptr<EncFS_Opts> opts;
|
||||||
|
|
||||||
boost::shared_ptr<Cipher> cipher;
|
boost::shared_ptr<Cipher> cipher;
|
||||||
|
@ -48,7 +48,7 @@ public:
|
|||||||
FileIO();
|
FileIO();
|
||||||
virtual ~FileIO();
|
virtual ~FileIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const =0;
|
virtual Interface interface() const =0;
|
||||||
|
|
||||||
// default implementation returns 1, meaning this is not block oriented.
|
// default implementation returns 1, meaning this is not block oriented.
|
||||||
virtual int blockSize() const;
|
virtual int blockSize() const;
|
||||||
|
@ -80,7 +80,7 @@ FileNode::FileNode(DirNode *parent_, const FSConfigPtr &cfg,
|
|||||||
shared_ptr<FileIO> rawIO( new RawFileIO( _cname ) );
|
shared_ptr<FileIO> rawIO( new RawFileIO( _cname ) );
|
||||||
io = shared_ptr<FileIO>( new CipherFileIO( rawIO, fsConfig ));
|
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));
|
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_);
|
rDebug("calling setIV on %s", cipherName_);
|
||||||
if(setIVFirst)
|
if(setIVFirst)
|
||||||
{
|
{
|
||||||
if(fsConfig->config->externalIVChaining && !setIV(io, iv))
|
if(fsConfig->config->external_iv() && !setIV(io, iv))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// now change the name..
|
// now change the name..
|
||||||
@ -151,7 +151,7 @@ bool FileNode::setName( const char *plaintextName_, const char *cipherName_,
|
|||||||
io->setFileName( cipherName_ );
|
io->setFileName( cipherName_ );
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fsConfig->config->externalIVChaining && !setIV(io, iv))
|
if(fsConfig->config->external_iv() && !setIV(io, iv))
|
||||||
{
|
{
|
||||||
_pname = oldPName;
|
_pname = oldPName;
|
||||||
_cname = oldCName;
|
_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.
|
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 boost::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( const std::string &rootdir, const EncfsConfig &config );
|
||||||
const boost::shared_ptr<EncFSConfig> &config );
|
|
||||||
|
|
||||||
class EncFS_Context;
|
class EncFS_Context;
|
||||||
|
|
||||||
RootPtr initFS( EncFS_Context *ctx, const boost::shared_ptr<EncFS_Opts> &opts );
|
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 );
|
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,
|
bool readV4Config( const char *configFile, EncfsConfig &config,
|
||||||
const boost::shared_ptr<EncFSConfig> &config,
|
|
||||||
struct ConfigInfo *);
|
struct ConfigInfo *);
|
||||||
bool writeV4Config( const char *configFile,
|
|
||||||
const boost::shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
bool readV5Config( const char *configFile,
|
bool readV5Config( const char *configFile, EncfsConfig &config,
|
||||||
const boost::shared_ptr<EncFSConfig> &config,
|
|
||||||
struct ConfigInfo *);
|
struct ConfigInfo *);
|
||||||
bool writeV5Config( const char *configFile,
|
|
||||||
const boost::shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
bool readV6Config( const char *configFile,
|
bool readV6Config( const char *configFile, EncfsConfig &config,
|
||||||
const boost::shared_ptr<EncFSConfig> &config,
|
struct ConfigInfo *);
|
||||||
|
|
||||||
|
bool readProtoConfig( const char *configFile, EncfsConfig &config,
|
||||||
struct ConfigInfo *);
|
struct ConfigInfo *);
|
||||||
bool writeV6Config( const char *configFile,
|
|
||||||
const boost::shared_ptr<EncFSConfig> &config);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,205 +22,69 @@
|
|||||||
#include <rlog/rlog.h>
|
#include <rlog/rlog.h>
|
||||||
#include <rlog/RLogChannel.h>
|
#include <rlog/RLogChannel.h>
|
||||||
|
|
||||||
using namespace rel;
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
|
|
||||||
static RLogChannel * Info = DEF_CHANNEL( "info/iface", Log_Info );
|
static RLogChannel * Info = DEF_CHANNEL( "info/iface", Log_Info );
|
||||||
|
|
||||||
Interface::Interface(const char *name_, int Current, int Revision, int Age)
|
bool implements(const Interface &A, const Interface &B)
|
||||||
: _name( name_ )
|
|
||||||
, _current( Current )
|
|
||||||
, _revision( Revision )
|
|
||||||
, _age( Age )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Interface::Interface(const std::string &name_, int Current,
|
|
||||||
int Revision, int Age)
|
|
||||||
: _name( name_ )
|
|
||||||
, _current( Current )
|
|
||||||
, _revision( Revision )
|
|
||||||
, _age( Age )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Interface::Interface(const Interface &src)
|
|
||||||
: _name( src._name )
|
|
||||||
, _current( src._current )
|
|
||||||
, _revision( src._revision )
|
|
||||||
, _age( src._age )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
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)",
|
rLog(Info, "checking if %s(%i:%i:%i) implements %s(%i:%i:%i)",
|
||||||
name().c_str(), current(), revision(), age(),
|
A.name().c_str(), A.major(), A.minor(), A.age(),
|
||||||
B.name().c_str(), B.current(), B.revision(), B.age());
|
B.name().c_str(), B.major(), B.minor(), B.age());
|
||||||
|
|
||||||
if( name() != B.name() )
|
if( A.name() != B.name() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int currentDiff = current() - B.current();
|
int currentDiff = A.major() - B.major();
|
||||||
return ( currentDiff >= 0 && currentDiff <= age() );
|
return ( currentDiff >= 0 && currentDiff <= (int)A.age() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Interface makeInterface(const char *name, int major, int minor, int age)
|
||||||
bool operator < (const Interface &A, const Interface &B)
|
|
||||||
{
|
{
|
||||||
if( A.name() == B.name() )
|
Interface iface;
|
||||||
{
|
iface.set_name(name);
|
||||||
return ( diffSum(A,B) < EqualVersion );
|
iface.set_major(major);
|
||||||
} else
|
iface.set_minor(minor);
|
||||||
return A.name() < B.name();
|
iface.set_age(age);
|
||||||
|
return iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator > (const Interface &A, const Interface &B)
|
ConfigVar & operator << (ConfigVar &dst, const Interface &iface)
|
||||||
{
|
{
|
||||||
if( A.name() == B.name() )
|
dst << iface.name() << (int)iface.major() << (int)iface.minor() << (int)iface.age();
|
||||||
{
|
|
||||||
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;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConfigVar & operator >> (const ConfigVar &src, Interface &iface)
|
const ConfigVar & operator >> (const ConfigVar &src, Interface &iface)
|
||||||
{
|
{
|
||||||
src >> iface.name();
|
src >> *iface.mutable_name();
|
||||||
src >> iface.current();
|
int major, minor, age;
|
||||||
src >> iface.revision();
|
src >> major >> minor >> age;
|
||||||
src >> iface.age();
|
iface.set_major(major);
|
||||||
|
iface.set_minor(minor);
|
||||||
|
iface.set_age(age);
|
||||||
return src;
|
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_
|
#define _Interface_incl_
|
||||||
|
|
||||||
#include <string>
|
#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;
|
class ConfigVar;
|
||||||
|
const ConfigVar & operator >> (const ConfigVar &, Interface &);
|
||||||
|
const XmlValuePtr & operator >> (const XmlValuePtr &, Interface &);
|
||||||
|
|
||||||
// part of REL library..
|
bool operator != (const Interface &a, const Interface &b);
|
||||||
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);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "MemoryPool.h"
|
#include "MemoryPool.h"
|
||||||
#include "FileUtils.h"
|
#include "FileUtils.h"
|
||||||
|
#include "config.pb.h"
|
||||||
|
|
||||||
#include <rlog/rlog.h>
|
#include <rlog/rlog.h>
|
||||||
#include <rlog/Error.h>
|
#include <rlog/Error.h>
|
||||||
@ -29,7 +30,6 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
using namespace rel;
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
using boost::dynamic_pointer_cast;
|
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
|
// compatible, except at a high level by checking a revision number for the
|
||||||
// filesystem...
|
// 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)
|
int dataBlockSize(const FSConfigPtr &cfg)
|
||||||
{
|
{
|
||||||
return cfg->config->blockSize
|
return cfg->config->block_size()
|
||||||
- cfg->config->blockMACBytes
|
- cfg->config->block_mac_bytes()
|
||||||
- cfg->config->blockMACRandBytes;
|
- cfg->config->block_mac_rand_bytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base,
|
MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base,
|
||||||
@ -63,23 +63,23 @@ MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base,
|
|||||||
, base( _base )
|
, base( _base )
|
||||||
, cipher( cfg->cipher )
|
, cipher( cfg->cipher )
|
||||||
, key( cfg->key )
|
, key( cfg->key )
|
||||||
, macBytes( cfg->config->blockMACBytes )
|
, macBytes( cfg->config->block_mac_bytes() )
|
||||||
, randBytes( cfg->config->blockMACRandBytes )
|
, randBytes( cfg->config->block_mac_rand_bytes() )
|
||||||
, warnOnly( cfg->opts->forceDecode )
|
, warnOnly( cfg->opts->forceDecode )
|
||||||
{
|
{
|
||||||
rAssert( macBytes >= 0 && macBytes <= 8 );
|
rAssert( macBytes >= 0 && macBytes <= 8 );
|
||||||
rAssert( randBytes >= 0 );
|
rAssert( randBytes >= 0 );
|
||||||
rLog(Info, "fs block size = %i, macBytes = %i, randBytes = %i",
|
rLog(Info, "fs block size = %i, macBytes = %i, randBytes = %i",
|
||||||
cfg->config->blockSize,
|
cfg->config->block_size(),
|
||||||
cfg->config->blockMACBytes,
|
cfg->config->block_mac_bytes(),
|
||||||
cfg->config->blockMACRandBytes);
|
cfg->config->block_mac_rand_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
MACFileIO::~MACFileIO()
|
MACFileIO::~MACFileIO()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
rel::Interface MACFileIO::interface() const
|
Interface MACFileIO::interface() const
|
||||||
{
|
{
|
||||||
return MACFileIO_iface;
|
return MACFileIO_iface;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
MACFileIO();
|
MACFileIO();
|
||||||
virtual ~MACFileIO();
|
virtual ~MACFileIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
virtual void setFileName( const char *fileName );
|
virtual void setFileName( const char *fileName );
|
||||||
virtual const char *getFileName() const;
|
virtual const char *getFileName() const;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
include $(top_srcdir)/Makefile.common
|
include $(top_srcdir)/Makefile.common
|
||||||
|
|
||||||
ALL_INCLUDES = @RLOG_CFLAGS@ @OPENSSL_CFLAGS@ @BOOST_CPPFLAGS@
|
ALL_INCLUDES = @RLOG_CFLAGS@ @OPENSSL_CFLAGS@ @BOOST_CPPFLAGS@
|
||||||
|
ALL_INCLUDES += @PROTOBUF_CFLAGS@
|
||||||
ALL_LDFLAGS = @RLOG_LIBS@ @OPENSSL_LIBS@ @BOOST_LDFLAGS@
|
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
|
INCLUDES = $(all_includes) -I../intl
|
||||||
|
|
||||||
@ -47,10 +49,10 @@ endif
|
|||||||
# : : 0 => no new interfaces, but breaks old apps
|
# : : 0 => no new interfaces, but breaks old apps
|
||||||
# : +1 : => internal changes, nothing breaks
|
# : +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@ \
|
libencfs_la_LIBADD = @RLOG_LIBS@ \
|
||||||
@OPENSSL_LIBS@ \
|
@OPENSSL_LIBS@ \
|
||||||
@BOOST_SERIALIZATION_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
|
@BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
|
||||||
|
|
||||||
EXTRASRC = ../intl/autosprintf.cpp
|
EXTRASRC = ../intl/autosprintf.cpp
|
||||||
if BUILD_OPENSSL
|
if BUILD_OPENSSL
|
||||||
@ -62,6 +64,7 @@ endif
|
|||||||
libencfs_la_SOURCES = \
|
libencfs_la_SOURCES = \
|
||||||
readpassphrase.cpp \
|
readpassphrase.cpp \
|
||||||
base64.cpp \
|
base64.cpp \
|
||||||
|
config.pb.cc \
|
||||||
ConfigReader.cpp \
|
ConfigReader.cpp \
|
||||||
ConfigVar.cpp \
|
ConfigVar.cpp \
|
||||||
Context.cpp \
|
Context.cpp \
|
||||||
@ -83,6 +86,7 @@ libencfs_la_SOURCES = \
|
|||||||
FileNode.cpp \
|
FileNode.cpp \
|
||||||
FileUtils.cpp \
|
FileUtils.cpp \
|
||||||
openssl.cpp \
|
openssl.cpp \
|
||||||
|
XmlReader.cpp \
|
||||||
${EXTRASRC}
|
${EXTRASRC}
|
||||||
|
|
||||||
|
|
||||||
@ -109,6 +113,7 @@ noinst_HEADERS = \
|
|||||||
CipherKey.h \
|
CipherKey.h \
|
||||||
ConfigReader.h \
|
ConfigReader.h \
|
||||||
ConfigVar.h \
|
ConfigVar.h \
|
||||||
|
config.pb.h \
|
||||||
Context.h \
|
Context.h \
|
||||||
DirNode.h \
|
DirNode.h \
|
||||||
encfs.h \
|
encfs.h \
|
||||||
@ -134,8 +139,14 @@ noinst_HEADERS = \
|
|||||||
man_MANS=encfs.1 encfsctl.1
|
man_MANS=encfs.1 encfsctl.1
|
||||||
EXTRA_DIST = encfs.pod encfsctl.pod encfs.1 encfsctl.1 encfs-man.html
|
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
|
if BUILD_MAN
|
||||||
SUFFIXES = .1 .pod
|
|
||||||
# since we have POD2MAN, we can specify how to rebuild encfs.1 if necessary
|
# since we have POD2MAN, we can specify how to rebuild encfs.1 if necessary
|
||||||
.pod.1:
|
.pod.1:
|
||||||
@POD2MAN@ --section=1 --release=@VERSION@ --center="Encrypted Filesystem" $< $@
|
@POD2MAN@ --section=1 --release=@VERSION@ --center="Encrypted Filesystem" $< $@
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||||
#include <valgrind/memcheck.h>
|
#include <valgrind/memcheck.h>
|
||||||
#else
|
#else
|
||||||
@ -34,6 +36,7 @@
|
|||||||
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
|
|
||||||
|
# include <openssl/crypto.h>
|
||||||
# include <openssl/buffer.h>
|
# include <openssl/buffer.h>
|
||||||
#define BLOCKDATA( BLOCK ) (unsigned char*)BLOCK->data->data
|
#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();
|
void destroyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SecureMem
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
SecureMem(int len);
|
||||||
|
~SecureMem();
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include "NullNameIO.h"
|
#include "NullNameIO.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rel;
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
|
|
||||||
#define REF_MODULE(TYPE) \
|
#define REF_MODULE(TYPE) \
|
||||||
@ -130,7 +129,7 @@ shared_ptr<NameIO> NameIO::New( const Interface &iface,
|
|||||||
NameIOMap_t::const_iterator end = gNameIOMap->end();
|
NameIOMap_t::const_iterator end = gNameIOMap->end();
|
||||||
for(it = gNameIOMap->begin(); it != end; ++it)
|
for(it = gNameIOMap->begin(); it != end; ++it)
|
||||||
{
|
{
|
||||||
if( it->second.iface.implements( iface ))
|
if( implements(it->second.iface, iface ))
|
||||||
{
|
{
|
||||||
Constructor fn = it->second.constructor;
|
Constructor fn = it->second.constructor;
|
||||||
result = (*fn)( iface, cipher, key );
|
result = (*fn)( iface, cipher, key );
|
||||||
|
@ -32,33 +32,33 @@ class Cipher;
|
|||||||
class NameIO
|
class NameIO
|
||||||
{
|
{
|
||||||
public:
|
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);
|
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
||||||
|
|
||||||
struct Algorithm
|
struct Algorithm
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
rel::Interface iface;
|
Interface iface;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::list<Algorithm> AlgorithmList;
|
typedef std::list<Algorithm> AlgorithmList;
|
||||||
static AlgorithmList GetAlgorithmList( bool includeHidden = false );
|
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);
|
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
||||||
static shared_ptr<NameIO> New( const std::string &name,
|
static shared_ptr<NameIO> New( const std::string &name,
|
||||||
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
const shared_ptr<Cipher> &cipher, const CipherKey &key);
|
||||||
|
|
||||||
static bool Register( const char *name, const char *description,
|
static bool Register( const char *name, const char *description,
|
||||||
const rel::Interface &iface, Constructor constructor,
|
const Interface &iface, Constructor constructor,
|
||||||
bool hidden = false);
|
bool hidden = false);
|
||||||
|
|
||||||
|
|
||||||
NameIO();
|
NameIO();
|
||||||
virtual ~NameIO();
|
virtual ~NameIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const =0;
|
virtual Interface interface() const =0;
|
||||||
|
|
||||||
void setChainedNameIV( bool enable );
|
void setChainedNameIV( bool enable );
|
||||||
bool getChainedNameIV() const;
|
bool getChainedNameIV() const;
|
||||||
|
@ -26,13 +26,12 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rel;
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
using boost::dynamic_pointer_cast;
|
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 NullKeyRange(0);
|
||||||
static Range NullBlockRange(1,4096,1);
|
static Range NullBlockRange(1,4096,1);
|
||||||
|
|
||||||
|
@ -28,13 +28,13 @@
|
|||||||
*/
|
*/
|
||||||
class NullCipher : public Cipher
|
class NullCipher : public Cipher
|
||||||
{
|
{
|
||||||
rel::Interface iface;
|
Interface iface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NullCipher(const rel::Interface &iface);
|
NullCipher(const Interface &iface);
|
||||||
virtual ~NullCipher();
|
virtual ~NullCipher();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
// create a new key based on a password
|
// create a new key based on a password
|
||||||
virtual CipherKey newKey(const char *password, int passwdLength,
|
virtual CipherKey newKey(const char *password, int passwdLength,
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace rel;
|
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
|
|
||||||
static shared_ptr<NameIO> NewNNIO( const Interface &,
|
static shared_ptr<NameIO> NewNNIO( const Interface &,
|
||||||
@ -31,7 +30,7 @@ static shared_ptr<NameIO> NewNNIO( const Interface &,
|
|||||||
return shared_ptr<NameIO>( new NullNameIO() );
|
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",
|
static bool NullNameIO_registered = NameIO::Register("Null",
|
||||||
"No encryption of filenames", NNIOIface, NewNNIO);
|
"No encryption of filenames", NNIOIface, NewNNIO);
|
||||||
|
|
||||||
|
@ -23,13 +23,13 @@
|
|||||||
class NullNameIO : public NameIO
|
class NullNameIO : public NameIO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static rel::Interface CurrentInterface();
|
static Interface CurrentInterface();
|
||||||
|
|
||||||
NullNameIO( );
|
NullNameIO( );
|
||||||
|
|
||||||
virtual ~NullNameIO();
|
virtual ~NullNameIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
||||||
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
virtual int maxDecodedNameLen( int encodedNameLen ) const;
|
||||||
|
@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
using namespace std;
|
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;
|
(void)iface;
|
||||||
return new RawFileIO();
|
return new RawFileIO();
|
||||||
@ -82,7 +82,7 @@ RawFileIO::~RawFileIO()
|
|||||||
close( _fd );
|
close( _fd );
|
||||||
}
|
}
|
||||||
|
|
||||||
rel::Interface RawFileIO::interface() const
|
Interface RawFileIO::interface() const
|
||||||
{
|
{
|
||||||
return RawFileIO_iface;
|
return RawFileIO_iface;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
RawFileIO( const std::string &fileName );
|
RawFileIO( const std::string &fileName );
|
||||||
virtual ~RawFileIO();
|
virtual ~RawFileIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
virtual void setFileName( const char *fileName );
|
virtual void setFileName( const char *fileName );
|
||||||
virtual const char *getFileName() const;
|
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
|
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.
|
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
|
DEPRECATED: this is here for backward compatibilty only. Use PBKDF
|
||||||
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.
|
|
||||||
*/
|
*/
|
||||||
int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
||||||
const unsigned char *data, int dataLen,
|
const unsigned char *data, int dataLen,
|
||||||
@ -103,7 +100,7 @@ int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int toCopy = MIN( nkey, mds - offset );
|
int toCopy = MIN( nkey, (int)mds - offset );
|
||||||
if( toCopy )
|
if( toCopy )
|
||||||
{
|
{
|
||||||
memcpy( key, mdBuf+offset, toCopy );
|
memcpy( key, mdBuf+offset, toCopy );
|
||||||
@ -111,7 +108,7 @@ int BytesToKey( int keyLen, int ivLen, const EVP_MD *md,
|
|||||||
nkey -= toCopy;
|
nkey -= toCopy;
|
||||||
offset += toCopy;
|
offset += toCopy;
|
||||||
}
|
}
|
||||||
toCopy = MIN( niv, mds - offset );
|
toCopy = MIN( niv, (int)mds - offset );
|
||||||
if( toCopy )
|
if( toCopy )
|
||||||
{
|
{
|
||||||
memcpy( iv, mdBuf+offset, 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:1 adds support for Message Digest function interface
|
||||||
// - Version 2:2 adds PBKDF2 for password derivation
|
// - Version 2:2 adds PBKDF2 for password derivation
|
||||||
// - Version 3:0 adds a new IV mechanism
|
// - Version 3:0 adds a new IV mechanism
|
||||||
static Interface BlowfishInterface( "ssl/blowfish", 3, 0, 2 );
|
static Interface BlowfishInterface = makeInterface( "ssl/blowfish", 3, 0, 2 );
|
||||||
static Interface AESInterface( "ssl/aes", 3, 0, 2 );
|
static Interface AESInterface = makeInterface( "ssl/aes", 3, 0, 2 );
|
||||||
|
|
||||||
#if defined(HAVE_EVP_BF)
|
#if defined(HAVE_EVP_BF)
|
||||||
|
|
||||||
@ -275,19 +272,20 @@ SSLKey::SSLKey(int keySize_, int ivLength_)
|
|||||||
this->ivLength = ivLength_;
|
this->ivLength = ivLength_;
|
||||||
pthread_mutex_init( &mutex, 0 );
|
pthread_mutex_init( &mutex, 0 );
|
||||||
buffer = (unsigned char *)OPENSSL_malloc( keySize + ivLength );
|
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
|
// most likely fails unless we're running as root, or a user-page-lock
|
||||||
// kernel patch is applied..
|
// kernel patch is applied..
|
||||||
mlock( buffer, keySize + ivLength );
|
mlock( buffer, keySize + ivLength );
|
||||||
|
|
||||||
|
memset( buffer, 0, keySize + ivLength );
|
||||||
}
|
}
|
||||||
|
|
||||||
SSLKey::~SSLKey()
|
SSLKey::~SSLKey()
|
||||||
{
|
{
|
||||||
memset( buffer, 0, keySize + ivLength );
|
memset( buffer, 0, keySize + ivLength );
|
||||||
|
|
||||||
OPENSSL_free( buffer );
|
|
||||||
munlock( buffer, keySize + ivLength );
|
munlock( buffer, keySize + ivLength );
|
||||||
|
OPENSSL_free( buffer );
|
||||||
|
|
||||||
keySize = 0;
|
keySize = 0;
|
||||||
ivLength = 0;
|
ivLength = 0;
|
||||||
@ -370,7 +368,7 @@ SSL_Cipher::SSL_Cipher(const Interface &iface_,
|
|||||||
iface.name().c_str(), _keySize, _ivLength);
|
iface.name().c_str(), _keySize, _ivLength);
|
||||||
|
|
||||||
if( (EVP_CIPHER_key_length( _blockCipher ) != (int )_keySize)
|
if( (EVP_CIPHER_key_length( _blockCipher ) != (int )_keySize)
|
||||||
&& iface.current() == 1)
|
&& iface.major() == 1)
|
||||||
{
|
{
|
||||||
rWarning("Running in backward compatibilty mode for 1.0 - \n"
|
rWarning("Running in backward compatibilty mode for 1.0 - \n"
|
||||||
"key is really %i bits, not %i.\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) );
|
shared_ptr<SSLKey> key( new SSLKey( _keySize, _ivLength) );
|
||||||
|
|
||||||
int bytes = 0;
|
int bytes = 0;
|
||||||
if( iface.current() > 1 )
|
if( iface.major() > 1 )
|
||||||
{
|
{
|
||||||
// now we use BytesToKey, which can deal with Blowfish keys larger then
|
// now we use BytesToKey, which can deal with Blowfish keys larger then
|
||||||
// 128 bits.
|
// 128 bits.
|
||||||
@ -680,7 +678,7 @@ int SSL_Cipher::cipherBlockSize() const
|
|||||||
void SSL_Cipher::setIVec( unsigned char *ivec, uint64_t seed,
|
void SSL_Cipher::setIVec( unsigned char *ivec, uint64_t seed,
|
||||||
const shared_ptr<SSLKey> &key) const
|
const shared_ptr<SSLKey> &key) const
|
||||||
{
|
{
|
||||||
if (iface.current() >= 3)
|
if (iface.major() >= 3)
|
||||||
{
|
{
|
||||||
memcpy( ivec, IVData(key), _ivLength );
|
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
|
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
|
could get a victim to store a carefully crafted file, they could later
|
||||||
determine if the victim had the file in encrypted storage (without
|
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,
|
unsigned int seed,
|
||||||
const shared_ptr<SSLKey> &key) const
|
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 var1 = 0x060a4011 * seed;
|
||||||
unsigned int var2 = 0x0221040d * (seed ^ 0xD3FEA11C);
|
unsigned int var2 = 0x0221040d * (seed ^ 0xD3FEA11C);
|
||||||
|
|
||||||
|
@ -70,21 +70,21 @@ using boost::shared_ptr;
|
|||||||
*/
|
*/
|
||||||
class SSL_Cipher : public Cipher
|
class SSL_Cipher : public Cipher
|
||||||
{
|
{
|
||||||
rel::Interface iface;
|
Interface iface;
|
||||||
rel::Interface realIface;
|
Interface realIface;
|
||||||
const EVP_CIPHER *_blockCipher;
|
const EVP_CIPHER *_blockCipher;
|
||||||
const EVP_CIPHER *_streamCipher;
|
const EVP_CIPHER *_streamCipher;
|
||||||
unsigned int _keySize; // in bytes
|
unsigned int _keySize; // in bytes
|
||||||
unsigned int _ivLength;
|
unsigned int _ivLength;
|
||||||
|
|
||||||
public:
|
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,
|
const EVP_CIPHER *blockCipher, const EVP_CIPHER *streamCipher,
|
||||||
int keyLength);
|
int keyLength);
|
||||||
virtual ~SSL_Cipher();
|
virtual ~SSL_Cipher();
|
||||||
|
|
||||||
// returns the real interface, not the one we're emulating (if any)..
|
// 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
|
// create a new key based on a password
|
||||||
virtual CipherKey newKey(const char *password, int passwdLength,
|
virtual CipherKey newKey(const char *password, int passwdLength,
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace rel;
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static shared_ptr<NameIO> NewStreamNameIO( const Interface &iface,
|
static shared_ptr<NameIO> NewStreamNameIO( const Interface &iface,
|
||||||
@ -65,13 +64,13 @@ static bool StreamIO_registered = NameIO::Register("Stream",
|
|||||||
Interface StreamNameIO::CurrentInterface()
|
Interface StreamNameIO::CurrentInterface()
|
||||||
{
|
{
|
||||||
// implement major version 2, 1, and 0
|
// 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 shared_ptr<Cipher> &cipher,
|
||||||
const CipherKey &key )
|
const CipherKey &key )
|
||||||
: _interface( iface.current() )
|
: _interface( iface.major() )
|
||||||
, _cipher( cipher )
|
, _cipher( cipher )
|
||||||
, _key( key )
|
, _key( key )
|
||||||
{
|
{
|
||||||
|
@ -27,14 +27,14 @@ using boost::shared_ptr;
|
|||||||
class StreamNameIO : public NameIO
|
class StreamNameIO : public NameIO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static rel::Interface CurrentInterface();
|
static Interface CurrentInterface();
|
||||||
|
|
||||||
StreamNameIO( const rel::Interface &iface,
|
StreamNameIO( const Interface &iface,
|
||||||
const shared_ptr<Cipher> &cipher,
|
const shared_ptr<Cipher> &cipher,
|
||||||
const CipherKey &key );
|
const CipherKey &key );
|
||||||
virtual ~StreamNameIO();
|
virtual ~StreamNameIO();
|
||||||
|
|
||||||
virtual rel::Interface interface() const;
|
virtual Interface interface() const;
|
||||||
|
|
||||||
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
virtual int maxEncodedNameLen( int plaintextNameLen ) const;
|
||||||
virtual int maxDecodedNameLen( int encodedNameLen ) 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 ))
|
if( !checkDir( rootDir ))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
|
EncfsConfig config;
|
||||||
ConfigType type = readConfig( rootDir, config );
|
ConfigType type = readConfig( rootDir, config );
|
||||||
|
|
||||||
// show information stored in config..
|
// show information stored in config..
|
||||||
@ -194,24 +194,22 @@ static int showInfo( int argc, char **argv )
|
|||||||
case Config_V3:
|
case Config_V3:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n" << autosprintf(_("Version 3 configuration; "
|
cout << "\n" << autosprintf(_("Version 3 configuration; "
|
||||||
"created by %s\n"), config->creator.c_str());
|
"created by %s\n"), config.creator().c_str());
|
||||||
break;
|
break;
|
||||||
case Config_V4:
|
case Config_V4:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n" << autosprintf(_("Version 4 configuration; "
|
cout << "\n" << autosprintf(_("Version 4 configuration; "
|
||||||
"created by %s\n"), config->creator.c_str());
|
"created by %s\n"), config.creator().c_str());
|
||||||
break;
|
break;
|
||||||
case Config_V5:
|
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_V6:
|
||||||
|
case Config_V7:
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
cout << "\n" << autosprintf(_("Version 6 configuration; "
|
cout << "\n" << autosprintf(_("Version %i configuration; "
|
||||||
"created by %s (revision %i)\n"), config->creator.c_str(),
|
"created by %s (revision %i)\n"),
|
||||||
config->subVersion);
|
type,
|
||||||
|
config.creator().c_str(),
|
||||||
|
config.revision());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,9 +685,7 @@ static int cmd_showcruft( int argc, char **argv )
|
|||||||
|
|
||||||
int filesFound = showcruft( rootInfo, "/" );
|
int filesFound = showcruft( rootInfo, "/" );
|
||||||
|
|
||||||
cerr << autosprintf(
|
cerr << autosprintf("Found %i invalid file(s).", filesFound) << "\n";
|
||||||
ngettext("Found %i invalid file.", "Found %i invalid files.",
|
|
||||||
filesFound), filesFound) << "\n";
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -701,7 +697,7 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
|||||||
if( !checkDir( rootDir ))
|
if( !checkDir( rootDir ))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
|
EncfsConfig config;
|
||||||
ConfigType cfgType = readConfig( rootDir, config );
|
ConfigType cfgType = readConfig( rootDir, config );
|
||||||
|
|
||||||
if(cfgType == Config_None)
|
if(cfgType == Config_None)
|
||||||
@ -711,12 +707,11 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// instanciate proper cipher
|
// instanciate proper cipher
|
||||||
shared_ptr<Cipher> cipher = Cipher::New(
|
shared_ptr<Cipher> cipher = getCipher(config);
|
||||||
config->cipherIface, config->keySize );
|
|
||||||
if(!cipher)
|
if(!cipher)
|
||||||
{
|
{
|
||||||
cout << autosprintf(_("Unable to find specified cipher \"%s\"\n"),
|
cout << autosprintf(_("Unable to find specified cipher \"%s\"\n"),
|
||||||
config->cipherIface.name().c_str());
|
config.cipher().name().c_str());
|
||||||
return EXIT_FAILURE;
|
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");
|
cout << _("Enter current Encfs password\n");
|
||||||
if (annotate)
|
if (annotate)
|
||||||
cerr << "$PROMPT$ passwd" << endl;
|
cerr << "$PROMPT$ passwd" << endl;
|
||||||
CipherKey userKey = config->getUserKey( useStdin );
|
CipherKey userKey = getUserKey( config, useStdin );
|
||||||
if(!userKey)
|
if(!userKey)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
// decode volume key using user key -- at this point we detect an incorrect
|
// 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).
|
// 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)
|
if(!volumeKey)
|
||||||
{
|
{
|
||||||
@ -741,17 +737,15 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv )
|
|||||||
// Now, get New user key..
|
// Now, get New user key..
|
||||||
userKey.reset();
|
userKey.reset();
|
||||||
cout << _("Enter new Encfs password\n");
|
cout << _("Enter new Encfs password\n");
|
||||||
// reinitialize salt and iteration count
|
|
||||||
config->kdfIterations = 0; // generate new
|
|
||||||
|
|
||||||
|
// create new key
|
||||||
if( useStdin )
|
if( useStdin )
|
||||||
{
|
{
|
||||||
if (annotate)
|
if (annotate)
|
||||||
cerr << "$PROMPT$ new_passwd" << endl;
|
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..
|
// re-encode the volume key using the new user key and write it out..
|
||||||
int result = EXIT_FAILURE;
|
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 );
|
cipher->writeKey( volumeKey, keyBuf, userKey );
|
||||||
userKey.reset();
|
userKey.reset();
|
||||||
|
|
||||||
config->assignKeyData( keyBuf, encodedKeySize );
|
config.set_key( keyBuf, encodedKeySize );
|
||||||
delete[] keyBuf;
|
delete[] keyBuf;
|
||||||
|
|
||||||
if(saveConfig( cfgType, rootDir, config ))
|
if(saveConfig( rootDir, config ))
|
||||||
{
|
{
|
||||||
// password modified -- changes volume key of filesystem..
|
// password modified -- changes volume key of filesystem..
|
||||||
cout << _("Volume Key successfully updated.\n");
|
cout << _("Volume Key successfully updated.\n");
|
||||||
@ -816,7 +810,7 @@ int main(int argc, char **argv)
|
|||||||
slog->subscribeTo( GetGlobalChannel("error") );
|
slog->subscribeTo( GetGlobalChannel("error") );
|
||||||
slog->subscribeTo( GetGlobalChannel("warning") );
|
slog->subscribeTo( GetGlobalChannel("warning") );
|
||||||
#ifndef NO_DEBUG
|
#ifndef NO_DEBUG
|
||||||
//slog->subscribeTo( GetGlobalChannel("debug") );
|
slog->subscribeTo( GetGlobalChannel("debug") );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
|
@ -69,7 +69,6 @@ inline static int MAX(int a, int b)
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
using namespace rel;
|
|
||||||
using namespace gnu;
|
using namespace gnu;
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
using boost::scoped_ptr;
|
using boost::scoped_ptr;
|
||||||
|
@ -47,11 +47,12 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <google/protobuf/text_format.h>
|
||||||
|
|
||||||
#include <tr1/unordered_set>
|
#include <tr1/unordered_set>
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace rel;
|
|
||||||
using namespace rlog;
|
using namespace rlog;
|
||||||
|
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
@ -235,35 +236,28 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
|||||||
cipher->writeKey( key, keyBuf, encodingKey );
|
cipher->writeKey( key, keyBuf, encodingKey );
|
||||||
|
|
||||||
// store in config struct..
|
// store in config struct..
|
||||||
EncFSConfig cfg;
|
EncfsConfig cfg;
|
||||||
cfg.cipherIface = cipher->interface();
|
cfg.mutable_cipher()->MergeFrom(cipher->interface());
|
||||||
cfg.keySize = 8 * cipher->keySize();
|
cfg.set_key_size(8 * cipher->keySize());
|
||||||
cfg.blockSize = FSBlockSize;
|
cfg.set_block_size(FSBlockSize);
|
||||||
cfg.assignKeyData( keyBuf, encodedKeySize );
|
cfg.set_key( keyBuf, encodedKeySize );
|
||||||
|
|
||||||
// save config
|
// save config
|
||||||
string data;
|
string data;
|
||||||
{
|
google::protobuf::TextFormat::PrintToString(cfg, &data);
|
||||||
ostringstream st;
|
|
||||||
st << cfg;
|
|
||||||
data = st.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// read back in and check everything..
|
// read back in and check everything..
|
||||||
EncFSConfig cfg2;
|
EncfsConfig cfg2;
|
||||||
{
|
google::protobuf::TextFormat::ParseFromString(data, &cfg2);
|
||||||
istringstream st(data);
|
|
||||||
st >> cfg2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check..
|
// check..
|
||||||
rAssert( cfg.cipherIface.implements(cfg2.cipherIface) );
|
rAssert( implements(cfg.cipher(),cfg2.cipher()) );
|
||||||
rAssert( cfg.keySize == cfg2.keySize );
|
rAssert( cfg.key_size() == cfg2.key_size() );
|
||||||
rAssert( cfg.blockSize == cfg2.blockSize );
|
rAssert( cfg.block_size() == cfg2.block_size() );
|
||||||
|
|
||||||
// try decoding key..
|
// try decoding key..
|
||||||
|
|
||||||
CipherKey key2 = cipher->readKey( cfg2.getKeyData(), encodingKey );
|
CipherKey key2 = cipher->readKey( (unsigned char *)cfg2.key().data(), encodingKey );
|
||||||
if(!key2)
|
if(!key2)
|
||||||
{
|
{
|
||||||
if(verbose)
|
if(verbose)
|
||||||
@ -286,15 +280,15 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
|
|||||||
FSConfigPtr fsCfg = FSConfigPtr(new FSConfig);
|
FSConfigPtr fsCfg = FSConfigPtr(new FSConfig);
|
||||||
fsCfg->cipher = cipher;
|
fsCfg->cipher = cipher;
|
||||||
fsCfg->key = key;
|
fsCfg->key = key;
|
||||||
fsCfg->config.reset(new EncFSConfig);
|
fsCfg->config.reset(new EncfsConfig);
|
||||||
fsCfg->config->blockSize = FSBlockSize;
|
fsCfg->config->set_block_size(FSBlockSize);
|
||||||
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
cerr << "Testing name encode/decode (stream coding w/ IV chaining)\n";
|
cerr << "Testing name encode/decode (stream coding w/ IV chaining)\n";
|
||||||
{
|
{
|
||||||
fsCfg->opts.reset(new EncFS_Opts);
|
fsCfg->opts.reset(new EncFS_Opts);
|
||||||
fsCfg->opts->idleTracking = false;
|
fsCfg->opts->idleTracking = false;
|
||||||
fsCfg->config->uniqueIV = false;
|
fsCfg->config->set_unique_iv(false);
|
||||||
|
|
||||||
fsCfg->nameCoding.reset( new StreamNameIO(
|
fsCfg->nameCoding.reset( new StreamNameIO(
|
||||||
StreamNameIO::CurrentInterface(), cipher, key ) );
|
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";
|
cerr << "Testing name encode/decode (block coding w/ IV chaining)\n";
|
||||||
{
|
{
|
||||||
fsCfg->opts->idleTracking = false;
|
fsCfg->opts->idleTracking = false;
|
||||||
fsCfg->config->uniqueIV = false;
|
fsCfg->config->set_unique_iv(false);
|
||||||
fsCfg->nameCoding.reset( new BlockNameIO(
|
fsCfg->nameCoding.reset( new BlockNameIO(
|
||||||
BlockNameIO::CurrentInterface(), cipher, key,
|
BlockNameIO::CurrentInterface(), cipher, key,
|
||||||
cipher->cipherBlockSize() ) );
|
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";
|
cerr << "Testing name encode/decode (block coding w/ IV chaining, base32)\n";
|
||||||
{
|
{
|
||||||
fsCfg->opts->idleTracking = false;
|
fsCfg->opts->idleTracking = false;
|
||||||
fsCfg->config->uniqueIV = false;
|
fsCfg->config->set_unique_iv(false);
|
||||||
fsCfg->nameCoding.reset( new BlockNameIO(
|
fsCfg->nameCoding.reset( new BlockNameIO(
|
||||||
BlockNameIO::CurrentInterface(), cipher, key,
|
BlockNameIO::CurrentInterface(), cipher, key,
|
||||||
cipher->cipherBlockSize(), true ) );
|
cipher->cipherBlockSize(), true ) );
|
||||||
@ -503,8 +497,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
cerr << it->name
|
cerr << it->name
|
||||||
<< " ( " << it->iface.name() << " "
|
<< " ( " << it->iface.name() << " "
|
||||||
<< it->iface.current() << ":"
|
<< it->iface.major() << ":"
|
||||||
<< it->iface.revision() << ":"
|
<< it->iface.minor() << ":"
|
||||||
<< it->iface.age() << " ) : " << it->description << "\n";
|
<< it->iface.age() << " ) : " << it->description << "\n";
|
||||||
cerr << " - key length " << it->keyLength.min() << " to "
|
cerr << " - key length " << it->keyLength.min() << " to "
|
||||||
<< it->keyLength.max() << " , block size " << it->blockSize.min()
|
<< it->keyLength.max() << " , block size " << it->blockSize.min()
|
||||||
|
Loading…
Reference in New Issue
Block a user