Cleanup option passing to make it simpler to pass options around.

Add new initialization vector setup mode for new filesystems.


git-svn-id: http://encfs.googlecode.com/svn/trunk@59 db9cf616-1c43-0410-9cb8-a902689de0d6
This commit is contained in:
Valient Gough 2010-08-30 06:32:05 +00:00
parent 460d04057b
commit 17071239d8
24 changed files with 478 additions and 471 deletions

View File

@ -1,3 +1,13 @@
Sun Aug 29 2010 Valient Gough <vgough@pobox.com>
* new IV initialization
* tag version 1.7
Sat Aug 28 2010 Valient Gough <vgough@pobox.com>
* fix component configuration to ease adding flags or config
Thu Jun 17 2010 Valient Gough <vgough@pobox.com>
* bump version to 1.6
Mon Jun 14 2010 Valient Gough <vgough@pobox.com> Mon Jun 14 2010 Valient Gough <vgough@pobox.com>
* fix compile error for boost < 1.41 and change rWarning to rInfo * fix compile error for boost < 1.41 and change rWarning to rInfo
* fix compiler warnings about unused result from fgets * fix compiler warnings about unused result from fgets

View File

@ -1,10 +1,7 @@
dnl Process this file with autoconf to produce a configure script. 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
AM_INIT_AUTOMAKE(encfs, 1.5.1) dnl searches for some needed programs AM_INIT_AUTOMAKE(encfs, 1.7) dnl searches for some needed programs
RELEASE=1
AC_SUBST(RELEASE)
AC_CANONICAL_HOST AC_CANONICAL_HOST
AM_CONDITIONAL([DARWIN], AM_CONDITIONAL([DARWIN],

View File

@ -36,9 +36,9 @@ static void clearCache( IORequest &req, int blockSize )
req.dataLen = 0; req.dataLen = 0;
} }
BlockFileIO::BlockFileIO( int dataSize ) BlockFileIO::BlockFileIO( int blockSize, const FSConfigPtr &cfg )
: _blockSize( dataSize ) : _blockSize( blockSize )
, _allowHoles( false ) , _allowHoles( cfg->config->allowHoles )
{ {
rAssert( _blockSize > 1 ); rAssert( _blockSize > 1 );
_cache.data = new unsigned char [ _blockSize ]; _cache.data = new unsigned char [ _blockSize ];
@ -98,11 +98,6 @@ bool BlockFileIO::cacheWriteOneBlock( const IORequest &req )
return ok; return ok;
} }
void BlockFileIO::allowHoles( bool allow )
{
_allowHoles = allow;
}
ssize_t BlockFileIO::read( const IORequest &req ) const ssize_t BlockFileIO::read( const IORequest &req ) const
{ {
rAssert( _blockSize != 0 ); rAssert( _blockSize != 0 );

View File

@ -19,6 +19,7 @@
#define _BlockFileIO_incl_ #define _BlockFileIO_incl_
#include "FileIO.h" #include "FileIO.h"
#include "FSConfig.h"
/* /*
Implements block scatter / gather interface. Requires derived classes to Implements block scatter / gather interface. Requires derived classes to
@ -31,7 +32,7 @@
class BlockFileIO : public FileIO class BlockFileIO : public FileIO
{ {
public: public:
BlockFileIO(int blockDataSize); BlockFileIO( int blockSize, const FSConfigPtr &cfg );
virtual ~BlockFileIO(); virtual ~BlockFileIO();
// implemented in terms of blocks. // implemented in terms of blocks.
@ -40,11 +41,6 @@ public:
virtual int blockSize() const; virtual int blockSize() const;
// default is false, but setting this to true will allow holes to be stored
// in the file. Only works if supported by the underlying FileIO
// implementation..
virtual void allowHoles( bool allow );
protected: protected:
int truncate( off_t size, FileIO *base ); int truncate( off_t size, FileIO *base );

View File

@ -50,23 +50,23 @@ static bool checkSize( int fsBlockSize, int cipherBlockSize )
} }
CipherFileIO::CipherFileIO( const shared_ptr<FileIO> &_base, CipherFileIO::CipherFileIO( const shared_ptr<FileIO> &_base,
const shared_ptr<Cipher> &_cipher, const FSConfigPtr &cfg)
const CipherKey &_key, int fsBlockSize, : BlockFileIO( cfg->config->blockSize, cfg )
bool uniqueIV, bool _reverseEncryption )
: BlockFileIO( fsBlockSize )
, base( _base ) , base( _base )
, cipher( _cipher ) , haveHeader( cfg->config->uniqueIV )
, key( _key )
, haveHeader( uniqueIV )
, externalIV( 0 ) , externalIV( 0 )
, fileIV( 0 ) , fileIV( 0 )
, lastFlags( 0 ) , lastFlags( 0 )
, reverseEncryption( _reverseEncryption )
{ {
fsConfig = cfg;
cipher = cfg->cipher;
key = cfg->key;
static bool warnOnce = false; static bool warnOnce = false;
if(!warnOnce) if(!warnOnce)
warnOnce = checkSize( fsBlockSize, cipher->cipherBlockSize() ); warnOnce = checkSize( fsConfig->config->blockSize,
fsConfig->cipher->cipherBlockSize() );
} }
CipherFileIO::~CipherFileIO() CipherFileIO::~CipherFileIO()
@ -193,7 +193,8 @@ void CipherFileIO::initHeader( )
req.dataLen = 8; req.dataLen = 8;
base->read( req ); base->read( req );
cipher->streamDecode( buf, sizeof(buf), externalIV, key ); cipher->streamDecode( buf, sizeof(buf),
externalIV, key );
fileIV = 0; fileIV = 0;
for(int i=0; i<8; ++i) for(int i=0; i<8; ++i)
@ -277,13 +278,11 @@ ssize_t CipherFileIO::readOneBlock( const IORequest &req ) const
off_t blockNum = req.offset / bs; off_t blockNum = req.offset / bs;
ssize_t readSize = 0; ssize_t readSize = 0;
IORequest tmpReq = req;
if(haveHeader) if(haveHeader)
{
IORequest tmpReq = req;
tmpReq.offset += HEADER_SIZE; tmpReq.offset += HEADER_SIZE;
readSize = base->read( tmpReq ); readSize = base->read( tmpReq );
} else
readSize = base->read( req );
bool ok; bool ok;
if(readSize > 0) if(readSize > 0)
@ -293,10 +292,10 @@ ssize_t CipherFileIO::readOneBlock( const IORequest &req ) const
if(readSize != bs) if(readSize != bs)
{ {
ok = streamRead( req.data, (int)readSize, blockNum ^ fileIV); ok = streamRead( tmpReq.data, (int)readSize, blockNum ^ fileIV);
} else } else
{ {
ok = blockRead( req.data, (int)readSize, blockNum ^ fileIV); ok = blockRead( tmpReq.data, (int)readSize, blockNum ^ fileIV);
} }
if(!ok) if(!ok)
@ -352,7 +351,7 @@ bool CipherFileIO::writeOneBlock( const IORequest &req )
bool CipherFileIO::blockWrite( unsigned char *buf, int size, bool CipherFileIO::blockWrite( unsigned char *buf, int size,
uint64_t _iv64 ) const uint64_t _iv64 ) const
{ {
if (!reverseEncryption) if (!fsConfig->reverseEncryption)
return cipher->blockEncode( buf, size, _iv64, key ); return cipher->blockEncode( buf, size, _iv64, key );
else else
return cipher->blockDecode( buf, size, _iv64, key ); return cipher->blockDecode( buf, size, _iv64, key );
@ -361,7 +360,7 @@ bool CipherFileIO::blockWrite( unsigned char *buf, int size,
bool CipherFileIO::streamWrite( unsigned char *buf, int size, bool CipherFileIO::streamWrite( unsigned char *buf, int size,
uint64_t _iv64 ) const uint64_t _iv64 ) const
{ {
if (!reverseEncryption) if (!fsConfig->reverseEncryption)
return cipher->streamEncode( buf, size, _iv64, key ); return cipher->streamEncode( buf, size, _iv64, key );
else else
return cipher->streamDecode( buf, size, _iv64, key ); return cipher->streamDecode( buf, size, _iv64, key );
@ -371,7 +370,7 @@ bool CipherFileIO::streamWrite( unsigned char *buf, int size,
bool CipherFileIO::blockRead( unsigned char *buf, int size, bool CipherFileIO::blockRead( unsigned char *buf, int size,
uint64_t _iv64 ) const uint64_t _iv64 ) const
{ {
if (reverseEncryption) if (fsConfig->reverseEncryption)
return cipher->blockEncode( buf, size, _iv64, key ); return cipher->blockEncode( buf, size, _iv64, key );
else else
{ {
@ -391,7 +390,7 @@ bool CipherFileIO::blockRead( unsigned char *buf, int size,
bool CipherFileIO::streamRead( unsigned char *buf, int size, bool CipherFileIO::streamRead( unsigned char *buf, int size,
uint64_t _iv64 ) const uint64_t _iv64 ) const
{ {
if (reverseEncryption) if (fsConfig->reverseEncryption)
return cipher->streamEncode( buf, size, _iv64, key ); return cipher->streamEncode( buf, size, _iv64, key );
else else
return cipher->streamDecode( buf, size, _iv64, key ); return cipher->streamDecode( buf, size, _iv64, key );

View File

@ -20,6 +20,7 @@
#include "BlockFileIO.h" #include "BlockFileIO.h"
#include "CipherKey.h" #include "CipherKey.h"
#include "FileUtils.h"
#include <inttypes.h> #include <inttypes.h>
@ -34,9 +35,7 @@ class CipherFileIO : public BlockFileIO
{ {
public: public:
CipherFileIO( const boost::shared_ptr<FileIO> &base, CipherFileIO( const boost::shared_ptr<FileIO> &base,
const boost::shared_ptr<Cipher> &cipher, const FSConfigPtr &cfg);
const CipherKey &key, int blockSize,
bool uniqueIV, bool reverseEncryption );
virtual ~CipherFileIO(); virtual ~CipherFileIO();
virtual rel::Interface interface() const; virtual rel::Interface interface() const;
@ -70,8 +69,9 @@ private:
uint64_t iv64 ) const; uint64_t iv64 ) const;
boost::shared_ptr<FileIO> base; boost::shared_ptr<FileIO> base;
boost::shared_ptr<Cipher> cipher;
CipherKey key; FSConfigPtr fsConfig;
// if haveHeader is true, then we have a transparent file header which // if haveHeader is true, then we have a transparent file header which
// contains a 64 bit initialization vector. // contains a 64 bit initialization vector.
bool haveHeader; bool haveHeader;
@ -79,7 +79,9 @@ private:
uint64_t externalIV; uint64_t externalIV;
uint64_t fileIV; uint64_t fileIV;
int lastFlags; int lastFlags;
bool reverseEncryption;
boost::shared_ptr<Cipher> cipher;
CipherKey key;
}; };
#endif #endif

View File

@ -22,6 +22,7 @@
#include "Context.h" #include "Context.h"
#include "Mutex.h" #include "Mutex.h"
#include "FileUtils.h" #include "FileUtils.h"
#include "DirNode.h"
#include <rlog/rlog.h> #include <rlog/rlog.h>

View File

@ -31,6 +31,8 @@
using boost::shared_ptr; using boost::shared_ptr;
struct EncFS_Args; struct EncFS_Args;
struct EncFS_Opts; struct EncFS_Opts;
class FileNode;
class DirNode;
class EncFS_Context class EncFS_Context
{ {

View File

@ -302,7 +302,8 @@ void RenameOp::undo()
} }
DirNode::DirNode(EncFS_Context *_ctx, DirNode::DirNode(EncFS_Context *_ctx,
const string &sourceDir, const shared_ptr<Config> &_config) const string &sourceDir,
const FSConfigPtr &_config)
{ {
pthread_mutex_init( &mutex, 0 ); pthread_mutex_init( &mutex, 0 );
@ -310,14 +311,14 @@ DirNode::DirNode(EncFS_Context *_ctx,
ctx = _ctx; ctx = _ctx;
rootDir = sourceDir; rootDir = sourceDir;
config = _config; fsConfig = _config;
// make sure rootDir ends in '/', so that we can form a path by appending // make sure rootDir ends in '/', so that we can form a path by appending
// the rest.. // the rest..
if( rootDir[ rootDir.length()-1 ] != '/' ) if( rootDir[ rootDir.length()-1 ] != '/' )
rootDir.append( 1, '/'); rootDir.append( 1, '/');
naming = config->nameCoding; naming = fsConfig->nameCoding;
} }
DirNode::~DirNode() DirNode::~DirNode()
@ -689,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( config->externalIVChaining ) if( fsConfig->config->externalIVChaining )
{ {
rLog(Info, "hard links not supported with external IV chaining!"); rLog(Info, "hard links not supported with external IV chaining!");
} else } else
@ -745,16 +746,8 @@ shared_ptr<FileNode> DirNode::directLookup( const char *path )
{ {
return shared_ptr<FileNode>( return shared_ptr<FileNode>(
new FileNode( this, new FileNode( this,
config->fsSubVersion, fsConfig,
"unknown", path, "unknown", path ));
config->cipher, config->key,
config->blockSize, config->blockMACBytes,
config->blockMACRandBytes,
config->uniqueIV,
config->externalIVChaining,
config->forceDecode,
config->reverseEncryption,
config->allowHoles) );
} }
shared_ptr<FileNode> DirNode::findOrCreate( const char *plainName) shared_ptr<FileNode> DirNode::findOrCreate( const char *plainName)
@ -767,20 +760,11 @@ shared_ptr<FileNode> DirNode::findOrCreate( const char *plainName)
{ {
uint64_t iv = 0; uint64_t iv = 0;
string cipherName = naming->encodePath( plainName, &iv ); string cipherName = naming->encodePath( plainName, &iv );
node.reset( new FileNode( this, node.reset( new FileNode( this, fsConfig,
config->fsSubVersion,
plainName, plainName,
(rootDir + cipherName).c_str(), (rootDir + cipherName).c_str()));
config->cipher, config->key,
config->blockSize, config->blockMACBytes,
config->blockMACRandBytes,
config->uniqueIV,
config->externalIVChaining,
config->forceDecode,
config->reverseEncryption,
config->allowHoles) );
if(config->externalIVChaining) if(fsConfig->config->externalIVChaining)
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());

View File

@ -30,6 +30,7 @@
#include "FileNode.h" #include "FileNode.h"
#include "NameIO.h" #include "NameIO.h"
#include "CipherKey.h" #include "CipherKey.h"
#include "FSConfig.h"
using boost::shared_ptr; using boost::shared_ptr;
@ -87,38 +88,10 @@ namespace __gnu_cxx
class DirNode class DirNode
{ {
public: public:
struct Config
{
shared_ptr<Cipher> cipher; // cipher to use
CipherKey key; // cipher key to use
shared_ptr<NameIO> nameCoding; // filename encoding implementation
int fsSubVersion; // filesystem version number at creation
int blockSize; // file data block size
bool inactivityTimer; // enables inactivity tracking
int blockMACBytes; // >0 enables per-file-block MAC headers
int blockMACRandBytes; // random bytes in MAC headers
bool uniqueIV; // enable per-file initialization vectors
bool externalIVChaining;
bool forceDecode; // force decoding, even if errors are detected
bool reverseEncryption;
bool allowHoles; // allow holes in files
Config()
: fsSubVersion(0)
, blockSize(1)
, inactivityTimer( false )
, blockMACBytes( 0 )
, blockMACRandBytes( 0 )
, uniqueIV( false )
, externalIVChaining( false )
, forceDecode( false )
, reverseEncryption ( false )
, allowHoles( false )
{ }
};
// sourceDir points to where raw files are stored // sourceDir points to where raw files are stored
DirNode( EncFS_Context *ctx, DirNode(EncFS_Context *ctx,
const std::string &sourceDir, const shared_ptr<Config> &config ); const std::string &sourceDir,
const FSConfigPtr &config );
~DirNode(); ~DirNode();
// return the path to the root directory // return the path to the root directory
@ -207,9 +180,8 @@ private:
// passed in as configuration // passed in as configuration
std::string rootDir; std::string rootDir;
shared_ptr<Config> config; FSConfigPtr fsConfig;
// stored here to reduce access through config var..
shared_ptr<NameIO> naming; shared_ptr<NameIO> naming;
}; };

132
encfs/FSConfig.h Normal file
View File

@ -0,0 +1,132 @@
/*****************************************************************************
* Author: Valient Gough <vgough@pobox.com>
*
*****************************************************************************
* Copyright (c) 2010 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 _FSConfig_incl_
#define _FSConfig_incl_
#include "encfs.h"
#include "Interface.h"
#include "CipherKey.h"
#include <vector>
#include <boost/shared_ptr.hpp>
enum ConfigType
{
Config_None = 0,
Config_Prehistoric,
Config_V3,
Config_V4,
Config_V5,
Config_V6
};
class EncFS_Opts;
class Cipher;
class NameIO;
struct EncFSConfig
{
ConfigType cfgType;
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();
boost::shared_ptr<Cipher> getCipher() const;
// 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);
struct FSConfig
{
boost::shared_ptr<EncFSConfig> config;
boost::shared_ptr<EncFS_Opts> opts;
boost::shared_ptr<Cipher> cipher;
CipherKey key;
boost::shared_ptr<NameIO> nameCoding;
bool forceDecode; // force decode on MAC block failures
bool reverseEncryption; // reverse encryption operation
bool idleTracking; // turn on idle monitoring of filesystem
};
typedef boost::shared_ptr<FSConfig> FSConfigPtr;
#endif

View File

@ -63,13 +63,8 @@ using boost::dynamic_pointer_cast;
static RLogChannel *Info = DEF_CHANNEL("info/FileNode", Log_Info); static RLogChannel *Info = DEF_CHANNEL("info/FileNode", Log_Info);
FileNode::FileNode(DirNode *parent_, FileNode::FileNode(DirNode *parent_, const FSConfigPtr &cfg,
int fsSubVersion, const char *plaintextName_, const char *cipherName_)
const char *plaintextName_, const char *cipherName_,
const shared_ptr<Cipher> &dataCipher, const CipherKey &key,
int blockSize, int blockMACBytes, int blockMACRandBytes, bool uniqueIV,
bool externalIVChaining_, bool forceDecode, bool reverseEncryption_,
bool allowHoles )
{ {
pthread_mutex_init( &mutex, 0 ); pthread_mutex_init( &mutex, 0 );
@ -78,23 +73,15 @@ FileNode::FileNode(DirNode *parent_,
this->_pname = plaintextName_; this->_pname = plaintextName_;
this->_cname = cipherName_; this->_cname = cipherName_;
this->parent = parent_; this->parent = parent_;
this->externalIVChaining = externalIVChaining_;
this->reverseEncryption = reverseEncryption_; this->fsConfig = cfg;
// chain RawFileIO & CipherFileIO // chain RawFileIO & CipherFileIO
shared_ptr<FileIO> rawIO( new RawFileIO( _cname ) ); shared_ptr<FileIO> rawIO( new RawFileIO( _cname ) );
io = shared_ptr<FileIO>( io = shared_ptr<FileIO>( new CipherFileIO( rawIO, fsConfig ));
new CipherFileIO( rawIO, dataCipher, key, blockSize,
uniqueIV, reverseEncryption ));
if(blockMACBytes) if(cfg->config->blockMACBytes)
{ io = shared_ptr<FileIO>(new MACFileIO(io, fsConfig));
io = shared_ptr<FileIO>(new MACFileIO(io, dataCipher, key,
blockSize,blockMACBytes,blockMACRandBytes,forceDecode));
}
if(allowHoles)
dynamic_pointer_cast<BlockFileIO>(io)->allowHoles( allowHoles );
} }
FileNode::~FileNode() FileNode::~FileNode()
@ -140,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(externalIVChaining && !setIV(io, iv)) if(fsConfig->config->externalIVChaining && !setIV(io, iv))
return false; return false;
// now change the name.. // now change the name..
@ -164,7 +151,7 @@ bool FileNode::setName( const char *plaintextName_, const char *cipherName_,
io->setFileName( cipherName_ ); io->setFileName( cipherName_ );
} }
if(externalIVChaining && !setIV(io, iv)) if(fsConfig->config->externalIVChaining && !setIV(io, iv))
{ {
_pname = oldPName; _pname = oldPName;
_cname = oldCName; _cname = oldCName;

View File

@ -20,6 +20,7 @@
#include "encfs.h" #include "encfs.h"
#include "CipherKey.h" #include "CipherKey.h"
#include "FileUtils.h"
#include <inttypes.h> #include <inttypes.h>
#include <sys/types.h> #include <sys/types.h>
@ -33,18 +34,10 @@ using boost::shared_ptr;
class FileNode class FileNode
{ {
public: public:
FileNode(DirNode *parent, FileNode(DirNode *parent,
int fsSubVersion, // version number for the filesystem const FSConfigPtr &cfg,
const char *plaintextName, const char *plaintextName,
const char *cipherName, const char *cipherName);
const shared_ptr<Cipher> &cipher, const CipherKey &key, int blockSize,
int blockMACBytes, // per-block random bytes in header
int blockMACRandBytes, // per-block random bytes in header
bool uniqueIV, // enable per-file initialization vectors
bool externalIVChaining,
bool forceDecode, // decode, even if decoding errors are detected
bool reverseEncryption,
bool allowHoles );
~FileNode(); ~FileNode();
const char *plaintextName() const; const char *plaintextName() const;
@ -86,8 +79,8 @@ private:
// truncate() which may result in multiple calls down to the FileIO // truncate() which may result in multiple calls down to the FileIO
// level. // level.
mutable pthread_mutex_t mutex; mutable pthread_mutex_t mutex;
bool externalIVChaining;
bool reverseEncryption; FSConfigPtr fsConfig;
shared_ptr<FileIO> io; shared_ptr<FileIO> io;
std::string _pname; // plaintext name std::string _pname; // plaintext name

View File

@ -29,6 +29,7 @@
#include "FileUtils.h" #include "FileUtils.h"
#include "ConfigReader.h" #include "ConfigReader.h"
#include "FSConfig.h"
#include "DirNode.h" #include "DirNode.h"
#include "Cipher.h" #include "Cipher.h"
@ -105,9 +106,11 @@ struct ConfigInfo
const char *fileName; const char *fileName;
ConfigType type; ConfigType type;
const char *environmentOverride; const char *environmentOverride;
bool (*loadFunc)(const char *fileName, EncFSConfig *config, bool (*loadFunc)(const char *fileName,
const boost::shared_ptr<EncFSConfig> &config,
ConfigInfo *cfg); ConfigInfo *cfg);
bool (*saveFunc)(const char *fileName, EncFSConfig *config); bool (*saveFunc)(const char *fileName,
const boost::shared_ptr<EncFSConfig> &config);
int currentSubVersion; int currentSubVersion;
int defaultSubVersion; int defaultSubVersion;
} ConfigFileMapping[] = { } ConfigFileMapping[] = {
@ -338,7 +341,7 @@ bool userAllowMkdir( const char *path, mode_t mode )
} }
ConfigType readConfig_load( ConfigInfo *nm, const char *path, ConfigType readConfig_load( ConfigInfo *nm, const char *path,
EncFSConfig *config ) const boost::shared_ptr<EncFSConfig> &config )
{ {
if( nm->loadFunc ) if( nm->loadFunc )
{ {
@ -364,7 +367,8 @@ ConfigType readConfig_load( ConfigInfo *nm, const char *path,
} }
} }
ConfigType readConfig( const string &rootDir, EncFSConfig *config ) ConfigType readConfig( const string &rootDir,
const boost::shared_ptr<EncFSConfig> &config )
{ {
ConfigInfo *nm = ConfigFileMapping; ConfigInfo *nm = ConfigFileMapping;
while(nm->fileName) while(nm->fileName)
@ -387,7 +391,8 @@ ConfigType readConfig( const string &rootDir, EncFSConfig *config )
return Config_None; return Config_None;
} }
bool readV6Config( const char *configFile, EncFSConfig *config, bool readV6Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config,
ConfigInfo *info) ConfigInfo *info)
{ {
(void)info; (void)info;
@ -413,7 +418,8 @@ bool readV6Config( const char *configFile, EncFSConfig *config,
} }
} }
bool readV5Config( const char *configFile, EncFSConfig *config, bool readV5Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config,
ConfigInfo *info) ConfigInfo *info)
{ {
bool ok = false; bool ok = false;
@ -470,7 +476,8 @@ bool readV5Config( const char *configFile, EncFSConfig *config,
return ok; return ok;
} }
bool readV4Config( const char *configFile, EncFSConfig *config, bool readV4Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config,
ConfigInfo *info) ConfigInfo *info)
{ {
bool ok = false; bool ok = false;
@ -511,7 +518,7 @@ bool readV4Config( const char *configFile, EncFSConfig *config,
} }
bool saveConfig( ConfigType type, const string &rootDir, bool saveConfig( ConfigType type, const string &rootDir,
EncFSConfig *config ) const boost::shared_ptr<EncFSConfig> &config )
{ {
bool ok = false; bool ok = false;
@ -545,15 +552,14 @@ bool saveConfig( ConfigType type, const string &rootDir,
return ok; return ok;
} }
bool writeV6Config( const char *configFile, EncFSConfig *config ) bool writeV6Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config )
{ {
fs::ofstream st( configFile ); fs::ofstream st( configFile );
if(!st.is_open()) if(!st.is_open())
return false; return false;
boost::archive::xml_oarchive oa(st); st << *config;
oa << BOOST_SERIALIZATION_NVP( config );
return true; return true;
} }
@ -573,7 +579,8 @@ std::istream &operator >> (std::istream &st, EncFSConfig &cfg)
return st; return st;
} }
bool writeV5Config( const char *configFile, EncFSConfig *config ) bool writeV5Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config )
{ {
ConfigReader cfg; ConfigReader cfg;
@ -595,7 +602,8 @@ bool writeV5Config( const char *configFile, EncFSConfig *config )
return cfg.save( configFile ); return cfg.save( configFile );
} }
bool writeV4Config( const char *configFile, EncFSConfig *config ) bool writeV4Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config )
{ {
ConfigReader cfg; ConfigReader cfg;
@ -1114,25 +1122,25 @@ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
alg.name.c_str(), keySize, blockSize); alg.name.c_str(), keySize, blockSize);
} }
EncFSConfig config; shared_ptr<EncFSConfig> config( new EncFSConfig );
config.cfgType = Config_V6; config->cfgType = Config_V6;
config.cipherIface = cipher->interface(); config->cipherIface = cipher->interface();
config.keySize = keySize; config->keySize = keySize;
config.blockSize = blockSize; config->blockSize = blockSize;
config.nameIface = nameIOIface; config->nameIface = nameIOIface;
config.creator = "EncFS " VERSION; config->creator = "EncFS " VERSION;
config.subVersion = V6SubVersion; config->subVersion = V6SubVersion;
config.blockMACBytes = blockMACBytes; config->blockMACBytes = blockMACBytes;
config.blockMACRandBytes = blockMACRandBytes; config->blockMACRandBytes = blockMACRandBytes;
config.uniqueIV = uniqueIV; config->uniqueIV = uniqueIV;
config.chainedNameIV = chainedIV; config->chainedNameIV = chainedIV;
config.externalIVChaining = externalIV; config->externalIVChaining = externalIV;
config.allowHoles = allowHoles; config->allowHoles = allowHoles;
config.salt.clear(); config->salt.clear();
config.kdfIterations = 0; // filled in by keying function config->kdfIterations = 0; // filled in by keying function
config.desiredKDFDuration = desiredKDFDuration; config->desiredKDFDuration = desiredKDFDuration;
cout << "\n"; cout << "\n";
// xgroup(setup) // xgroup(setup)
@ -1140,7 +1148,7 @@ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
"the following properties:") << endl; "the following properties:") << endl;
showFSInfo( config ); showFSInfo( config );
if( config.externalIVChaining ) if( config->externalIVChaining )
{ {
cout << cout <<
_("-------------------------- WARNING --------------------------\n") _("-------------------------- WARNING --------------------------\n")
@ -1170,16 +1178,16 @@ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
CipherKey userKey; CipherKey userKey;
rDebug( "useStdin: %i", useStdin ); rDebug( "useStdin: %i", useStdin );
if(useStdin) if(useStdin)
userKey = config.getUserKey( useStdin ); userKey = config->getUserKey( useStdin );
else if(!passwordProgram.empty()) else if(!passwordProgram.empty())
userKey = config.getUserKey( passwordProgram, rootDir ); userKey = config->getUserKey( passwordProgram, rootDir );
else else
userKey = config.getNewUserKey(); userKey = config->getNewUserKey();
cipher->writeKey( volumeKey, encodedKey, userKey ); cipher->writeKey( volumeKey, encodedKey, userKey );
userKey.reset(); userKey.reset();
config.assignKeyData(encodedKey, encodedKeySize); config->assignKeyData(encodedKey, encodedKeySize);
delete[] encodedKey; delete[] encodedKey;
if(!volumeKey) if(!volumeKey)
@ -1189,11 +1197,11 @@ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
return rootInfo; return rootInfo;
} }
if(!saveConfig( Config_V6, rootDir, &config )) if(!saveConfig( Config_V6, rootDir, config ))
return rootInfo; return rootInfo;
// fill in config struct // fill in config struct
shared_ptr<NameIO> nameCoder = NameIO::New( config.nameIface, shared_ptr<NameIO> nameCoder = NameIO::New( config->nameIface,
cipher, volumeKey ); cipher, volumeKey );
if(!nameCoder) if(!nameCoder)
{ {
@ -1203,49 +1211,43 @@ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
return rootInfo; return rootInfo;
} }
nameCoder->setChainedNameIV( config.chainedNameIV ); nameCoder->setChainedNameIV( config->chainedNameIV );
nameCoder->setReverseEncryption( reverseEncryption ); nameCoder->setReverseEncryption( reverseEncryption );
shared_ptr<DirNode::Config> dirNodeConfig (new DirNode::Config); FSConfigPtr fsConfig (new FSConfig);
dirNodeConfig->cipher = cipher; fsConfig->cipher = cipher;
dirNodeConfig->key = volumeKey; fsConfig->key = volumeKey;
dirNodeConfig->nameCoding = nameCoder; fsConfig->nameCoding = nameCoder;
dirNodeConfig->fsSubVersion = config.subVersion; fsConfig->config = config;
dirNodeConfig->blockSize = blockSize; fsConfig->forceDecode = forceDecode;
dirNodeConfig->inactivityTimer = enableIdleTracking; fsConfig->reverseEncryption = reverseEncryption;
dirNodeConfig->blockMACBytes = config.blockMACBytes; fsConfig->idleTracking = enableIdleTracking;
dirNodeConfig->blockMACRandBytes = config.blockMACRandBytes;
dirNodeConfig->uniqueIV = config.uniqueIV;
dirNodeConfig->externalIVChaining = config.externalIVChaining;
dirNodeConfig->forceDecode = forceDecode;
dirNodeConfig->reverseEncryption = reverseEncryption;
dirNodeConfig->allowHoles = config.allowHoles;
rootInfo = RootPtr( new EncFS_Root ); rootInfo = RootPtr( new EncFS_Root );
rootInfo->cipher = cipher; rootInfo->cipher = cipher;
rootInfo->volumeKey = volumeKey; rootInfo->volumeKey = volumeKey;
rootInfo->root = shared_ptr<DirNode>( rootInfo->root = shared_ptr<DirNode>(
new DirNode( ctx, rootDir, dirNodeConfig )); new DirNode( ctx, rootDir, fsConfig ));
return rootInfo; return rootInfo;
} }
void showFSInfo( const EncFSConfig &config ) void showFSInfo( const boost::shared_ptr<EncFSConfig> &config )
{ {
shared_ptr<Cipher> cipher = Cipher::New( config.cipherIface, -1 ); shared_ptr<Cipher> cipher = Cipher::New( config->cipherIface, -1 );
{ {
cout << autosprintf( cout << autosprintf(
// xgroup(diag) // xgroup(diag)
_("Filesystem cipher: \"%s\", version %i:%i:%i"), _("Filesystem cipher: \"%s\", version %i:%i:%i"),
config.cipherIface.name().c_str(), config.cipherIface.current(), config->cipherIface.name().c_str(), config->cipherIface.current(),
config.cipherIface.revision(), config.cipherIface.age()); config->cipherIface.revision(), config->cipherIface.age());
// check if we support this interface.. // check if we support this interface..
if(!cipher) if(!cipher)
cout << _(" (NOT supported)\n"); cout << _(" (NOT supported)\n");
else else
{ {
// if we're using a newer interface, show the version number // if we're using a newer interface, show the version number
if( config.cipherIface != cipher->interface() ) if( config->cipherIface != cipher->interface() )
{ {
Interface iface = cipher->interface(); Interface iface = cipher->interface();
// xgroup(diag) // xgroup(diag)
@ -1258,11 +1260,11 @@ void showFSInfo( const EncFSConfig &config )
{ {
// xgroup(diag) // xgroup(diag)
cout << autosprintf(_("Filename encoding: \"%s\", version %i:%i:%i"), cout << autosprintf(_("Filename encoding: \"%s\", version %i:%i:%i"),
config.nameIface.name().c_str(), config.nameIface.current(), config->nameIface.name().c_str(), config->nameIface.current(),
config.nameIface.revision(), config.nameIface.age()); config->nameIface.revision(), config->nameIface.age());
// check if we support the filename encoding interface.. // check if we support the filename encoding interface..
shared_ptr<NameIO> nameCoder = NameIO::New( config.nameIface, shared_ptr<NameIO> nameCoder = NameIO::New( config->nameIface,
cipher, CipherKey() ); cipher, CipherKey() );
if(!nameCoder) if(!nameCoder)
{ {
@ -1271,7 +1273,7 @@ void showFSInfo( const EncFSConfig &config )
} else } else
{ {
// if we're using a newer interface, show the version number // if we're using a newer interface, show the version number
if( config.nameIface != nameCoder->interface() ) if( config->nameIface != nameCoder->interface() )
{ {
Interface iface = nameCoder->interface(); Interface iface = nameCoder->interface();
cout << autosprintf(_(" (using %i:%i:%i)\n"), cout << autosprintf(_(" (using %i:%i:%i)\n"),
@ -1281,8 +1283,8 @@ void showFSInfo( const EncFSConfig &config )
} }
} }
{ {
cout << autosprintf(_("Key Size: %i bits"), config.keySize); cout << autosprintf(_("Key Size: %i bits"), config->keySize);
cipher = config.getCipher(); cipher = config->getCipher();
if(!cipher) if(!cipher)
{ {
// xgroup(diag) // xgroup(diag)
@ -1290,54 +1292,54 @@ void showFSInfo( const EncFSConfig &config )
} else } else
cout << "\n"; cout << "\n";
} }
if(config.kdfIterations > 0 && config.salt.size() > 0) if(config->kdfIterations > 0 && config->salt.size() > 0)
{ {
cout << autosprintf(_("Using PBKDF2, with %i iterations"), cout << autosprintf(_("Using PBKDF2, with %i iterations"),
config.kdfIterations) << "\n"; config->kdfIterations) << "\n";
cout << autosprintf(_("Salt Size: %i bits"), cout << autosprintf(_("Salt Size: %i bits"),
8*(int)config.salt.size()) << "\n"; 8*(int)config->salt.size()) << "\n";
} }
if(config.blockMACBytes) if(config->blockMACBytes)
{ {
if(config.subVersion < 20040813) if(config->subVersion < 20040813)
{ {
cout << autosprintf( cout << autosprintf(
// xgroup(diag) // xgroup(diag)
_("Block Size: %i bytes + %i byte MAC header"), _("Block Size: %i bytes + %i byte MAC header"),
config.blockSize, config->blockSize,
config.blockMACBytes + config.blockMACRandBytes) << endl; config->blockMACBytes + config->blockMACRandBytes) << endl;
} else } else
{ {
// new version stores the header as part of that block size.. // new version stores the header as part of that block size..
cout << autosprintf( cout << autosprintf(
// xgroup(diag) // xgroup(diag)
_("Block Size: %i bytes, including %i byte MAC header"), _("Block Size: %i bytes, including %i byte MAC header"),
config.blockSize, config->blockSize,
config.blockMACBytes + config.blockMACRandBytes) << endl; config->blockMACBytes + config->blockMACRandBytes) << endl;
} }
} else } else
{ {
// xgroup(diag) // xgroup(diag)
cout << autosprintf(_("Block Size: %i bytes"), config.blockSize); cout << autosprintf(_("Block Size: %i bytes"), config->blockSize);
cout << "\n"; cout << "\n";
} }
if(config.uniqueIV) if(config->uniqueIV)
{ {
// xgroup(diag) // xgroup(diag)
cout << _("Each file contains 8 byte header with unique IV data.\n"); cout << _("Each file contains 8 byte header with unique IV data.\n");
} }
if(config.chainedNameIV) if(config->chainedNameIV)
{ {
// xgroup(diag) // xgroup(diag)
cout << _("Filenames encoded using IV chaining mode.\n"); cout << _("Filenames encoded using IV chaining mode.\n");
} }
if(config.externalIVChaining) if(config->externalIVChaining)
{ {
// xgroup(diag) // xgroup(diag)
cout << _("File data IV is chained to filename IV.\n"); cout << _("File data IV is chained to filename IV.\n");
} }
if(config.allowHoles) if(config->allowHoles)
{ {
// xgroup(diag) // xgroup(diag)
cout << _("File holes passed through to ciphertext.\n"); cout << _("File holes passed through to ciphertext.\n");
@ -1359,16 +1361,12 @@ void EncFSConfig::assignKeyData(const std::string &in)
void EncFSConfig::assignKeyData(unsigned char *data, int len) void EncFSConfig::assignKeyData(unsigned char *data, int len)
{ {
keyData.resize(len); keyData.assign(data, data+len);
for(int i=0; i<len; ++i)
keyData[i] = data[i];
} }
void EncFSConfig::assignSaltData(unsigned char *data, int len) void EncFSConfig::assignSaltData(unsigned char *data, int len)
{ {
salt.resize(len); salt.assign(data, data+len);
for(int i=0; i<len; ++i)
salt[i] = data[i];
} }
unsigned char *EncFSConfig::getKeyData() const unsigned char *EncFSConfig::getKeyData() const
@ -1585,15 +1583,15 @@ CipherKey EncFSConfig::getNewUserKey()
RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts ) RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
{ {
RootPtr rootInfo; RootPtr rootInfo;
EncFSConfig config; boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
if(readConfig( opts->rootDir, &config ) != Config_None) if(readConfig( opts->rootDir, config ) != Config_None)
{ {
if(opts->reverseEncryption) if(opts->reverseEncryption)
{ {
if (config.blockMACBytes != 0 || config.blockMACRandBytes != 0 if (config->blockMACBytes != 0 || config->blockMACRandBytes != 0
|| config.uniqueIV == true || config.externalIVChaining == true || config->uniqueIV || config->externalIVChaining
|| config.chainedNameIV == true ) || config->chainedNameIV )
{ {
cout << _("The configuration loaded is not compatible with --reverse\n"); cout << _("The configuration loaded is not compatible with --reverse\n");
return rootInfo; return rootInfo;
@ -1601,14 +1599,14 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
} }
// first, instanciate the cipher. // first, instanciate the cipher.
shared_ptr<Cipher> cipher = config.getCipher(); shared_ptr<Cipher> cipher = config->getCipher();
if(!cipher) if(!cipher)
{ {
rError(_("Unable to find cipher %s, version %i:%i:%i"), rError(_("Unable to find cipher %s, version %i:%i:%i"),
config.cipherIface.name().c_str(), config->cipherIface.name().c_str(),
config.cipherIface.current(), config->cipherIface.current(),
config.cipherIface.revision(), config->cipherIface.revision(),
config.cipherIface.age()); config->cipherIface.age());
// xgroup(diag) // xgroup(diag)
cout << _("The requested cipher interface is not available\n"); cout << _("The requested cipher interface is not available\n");
return rootInfo; return rootInfo;
@ -1620,9 +1618,9 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
if(opts->passwordProgram.empty()) if(opts->passwordProgram.empty())
{ {
rDebug( "useStdin: %i", opts->useStdin ); rDebug( "useStdin: %i", opts->useStdin );
userKey = config.getUserKey( opts->useStdin ); userKey = config->getUserKey( opts->useStdin );
} else } else
userKey = config.getUserKey( opts->passwordProgram, opts->rootDir ); userKey = config->getUserKey( opts->passwordProgram, opts->rootDir );
if(!userKey) if(!userKey)
return rootInfo; return rootInfo;
@ -1630,7 +1628,7 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
rDebug("cipher key size = %i", cipher->encodedKeySize()); rDebug("cipher key size = %i", cipher->encodedKeySize());
// decode volume key.. // decode volume key..
CipherKey volumeKey = cipher->readKey( CipherKey volumeKey = cipher->readKey(
config.getKeyData(), userKey, opts->checkKey); config->getKeyData(), userKey, opts->checkKey);
userKey.reset(); userKey.reset();
if(!volumeKey) if(!volumeKey)
@ -1640,43 +1638,37 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts )
return rootInfo; return rootInfo;
} }
shared_ptr<NameIO> nameCoder = NameIO::New( config.nameIface, shared_ptr<NameIO> nameCoder = NameIO::New( config->nameIface,
cipher, volumeKey ); cipher, volumeKey );
if(!nameCoder) if(!nameCoder)
{ {
rError(_("Unable to find nameio interface %s, version %i:%i:%i"), rError(_("Unable to find nameio interface %s, version %i:%i:%i"),
config.nameIface.name().c_str(), config->nameIface.name().c_str(),
config.nameIface.current(), config->nameIface.current(),
config.nameIface.revision(), config->nameIface.revision(),
config.nameIface.age()); config->nameIface.age());
// xgroup(diag) // xgroup(diag)
cout << _("The requested filename coding interface is " cout << _("The requested filename coding interface is "
"not available\n"); "not available\n");
return rootInfo; return rootInfo;
} }
nameCoder->setChainedNameIV( config.chainedNameIV ); nameCoder->setChainedNameIV( config->chainedNameIV );
nameCoder->setReverseEncryption( opts->reverseEncryption ); nameCoder->setReverseEncryption( opts->reverseEncryption );
shared_ptr<DirNode::Config> dirNodeConfig (new DirNode::Config); FSConfigPtr fsConfig( new FSConfig );
dirNodeConfig->cipher = cipher; fsConfig->cipher = cipher;
dirNodeConfig->key = volumeKey; fsConfig->key = volumeKey;
dirNodeConfig->nameCoding = nameCoder; fsConfig->nameCoding = nameCoder;
dirNodeConfig->fsSubVersion = config.subVersion; fsConfig->config = config;
dirNodeConfig->blockSize = config.blockSize; fsConfig->forceDecode = opts->forceDecode;
dirNodeConfig->inactivityTimer = opts->idleTracking; fsConfig->reverseEncryption = opts->forceDecode;
dirNodeConfig->blockMACBytes = config.blockMACBytes;
dirNodeConfig->blockMACRandBytes = config.blockMACRandBytes;
dirNodeConfig->uniqueIV = config.uniqueIV;
dirNodeConfig->externalIVChaining = config.externalIVChaining;
dirNodeConfig->forceDecode = opts->forceDecode;
dirNodeConfig->reverseEncryption = opts->reverseEncryption;
rootInfo = RootPtr( new EncFS_Root ); rootInfo = RootPtr( new EncFS_Root );
rootInfo->cipher = cipher; rootInfo->cipher = cipher;
rootInfo->volumeKey = volumeKey; rootInfo->volumeKey = volumeKey;
rootInfo->root = shared_ptr<DirNode>( rootInfo->root = shared_ptr<DirNode>(
new DirNode( ctx, opts->rootDir, dirNodeConfig )); new DirNode( ctx, opts->rootDir, fsConfig ));
} else } else
{ {
if(opts->createIfNotFound) if(opts->createIfNotFound)

View File

@ -20,8 +20,8 @@
#include "encfs.h" #include "encfs.h"
#include "Interface.h" #include "Interface.h"
#include "DirNode.h"
#include "CipherKey.h" #include "CipherKey.h"
#include "FSConfig.h"
// true if the path points to an existing node (of any type) // true if the path points to an existing node (of any type)
bool fileExists( const char *fileName ); bool fileExists( const char *fileName );
@ -38,85 +38,8 @@ std::string parentDirectory( const std::string &path );
// do it and return true. // do it and return true.
bool userAllowMkdir( const char *dirPath, mode_t mode ); bool userAllowMkdir( const char *dirPath, mode_t mode );
enum ConfigType
{
Config_None = 0,
Config_Prehistoric,
Config_V3,
Config_V4,
Config_V5,
Config_V6
};
struct EncFSConfig
{
ConfigType cfgType;
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();
shared_ptr<Cipher> getCipher() const;
// 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);
};
std::ostream &operator << (std::ostream &os, const EncFSConfig &cfg);
std::istream &operator >> (std::istream &os, EncFSConfig &cfg);
class Cipher; class Cipher;
class DirNode;
struct EncFS_Root struct EncFS_Root
{ {
@ -130,18 +53,6 @@ struct EncFS_Root
typedef boost::shared_ptr<EncFS_Root> RootPtr; typedef boost::shared_ptr<EncFS_Root> RootPtr;
/*
Read existing config file. Looks for any supported configuration version.
*/
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,
EncFSConfig *config );
enum ConfigMode enum ConfigMode
{ {
Config_Prompt, Config_Prompt,
@ -170,21 +81,34 @@ struct EncFS_Opts
EncFS_Opts() EncFS_Opts()
{ {
createIfNotFound = true; createIfNotFound = true;
idleTracking = false; idleTracking = false;
mountOnDemand = false; mountOnDemand = false;
checkKey = true; checkKey = true;
forceDecode = false; forceDecode = false;
useStdin = false; useStdin = false;
ownerCreate = false; ownerCreate = false;
reverseEncryption = false; reverseEncryption = false;
configMode = Config_Prompt; configMode = Config_Prompt;
} }
}; };
/*
Read existing config file. Looks for any supported configuration version.
*/
ConfigType readConfig( const std::string &rootDir,
const boost::shared_ptr<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 );
class EncFS_Context; class EncFS_Context;
RootPtr initFS( EncFS_Context *ctx, const shared_ptr<EncFS_Opts> &opts ); RootPtr initFS( EncFS_Context *ctx, const boost::shared_ptr<EncFS_Opts> &opts );
RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir, RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
bool enableIdleTracking, bool enableIdleTracking,
@ -193,18 +117,24 @@ RootPtr createV6Config( EncFS_Context *ctx, const std::string &rootDir,
bool allowHoles, ConfigMode mode ); bool allowHoles, ConfigMode mode );
void showFSInfo( const EncFSConfig &config ); void showFSInfo( const boost::shared_ptr<EncFSConfig> &config );
bool readV4Config( const char *configFile, EncFSConfig *config, bool readV4Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config,
struct ConfigInfo *); struct ConfigInfo *);
bool writeV4Config( const char *configFile, EncFSConfig *config); bool writeV4Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config);
bool readV5Config( const char *configFile, EncFSConfig *config, bool readV5Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config,
struct ConfigInfo *); struct ConfigInfo *);
bool writeV5Config( const char *configFile, EncFSConfig *config); bool writeV5Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config);
bool readV6Config( const char *configFile, EncFSConfig *config, bool readV6Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config,
struct ConfigInfo *); struct ConfigInfo *);
bool writeV6Config( const char *configFile, EncFSConfig *config); bool writeV6Config( const char *configFile,
const boost::shared_ptr<EncFSConfig> &config);
#endif #endif

View File

@ -18,6 +18,7 @@
#include "MACFileIO.h" #include "MACFileIO.h"
#include "MemoryPool.h" #include "MemoryPool.h"
#include "FileUtils.h"
#include <rlog/rlog.h> #include <rlog/rlog.h>
#include <rlog/Error.h> #include <rlog/Error.h>
@ -48,23 +49,29 @@ static RLogChannel *Info = DEF_CHANNEL("info/MACFileIO", Log_Info);
// //
static rel::Interface MACFileIO_iface("FileIO/MAC", 2, 0, 0); static rel::Interface MACFileIO_iface("FileIO/MAC", 2, 0, 0);
int dataBlockSize(const FSConfigPtr &cfg)
{
return cfg->config->blockSize
- cfg->config->blockMACBytes
- cfg->config->blockMACRandBytes;
}
MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base, MACFileIO::MACFileIO( const shared_ptr<FileIO> &_base,
const shared_ptr<Cipher> &_cipher, const FSConfigPtr &cfg )
const CipherKey &_key, int fsBlockSize, : BlockFileIO( dataBlockSize( cfg ), cfg )
int _macBytes, int _randBytes,
bool warnOnlyMode )
: BlockFileIO( fsBlockSize - _macBytes - _randBytes )
, base( _base ) , base( _base )
, cipher( _cipher ) , cipher( cfg->cipher )
, key( _key ) , key( cfg->key )
, macBytes( _macBytes ) , macBytes( cfg->config->blockMACBytes )
, randBytes( _randBytes ) , randBytes( cfg->config->blockMACRandBytes )
, warnOnly( warnOnlyMode ) , 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",
fsBlockSize, macBytes, randBytes); cfg->config->blockSize,
cfg->config->blockMACBytes,
cfg->config->blockMACRandBytes);
} }
MACFileIO::~MACFileIO() MACFileIO::~MACFileIO()
@ -159,14 +166,6 @@ off_t MACFileIO::getSize() const
return size; return size;
} }
void MACFileIO::allowHoles( bool allow )
{
BlockFileIO::allowHoles( allow );
shared_ptr<BlockFileIO> bf = dynamic_pointer_cast<BlockFileIO>( base );
if(bf)
bf->allowHoles( allow );
}
ssize_t MACFileIO::readOneBlock( const IORequest &req ) const ssize_t MACFileIO::readOneBlock( const IORequest &req ) const
{ {
int headerSize = macBytes + randBytes; int headerSize = macBytes + randBytes;

View File

@ -32,10 +32,7 @@ public:
be made available.. be made available..
*/ */
MACFileIO( const shared_ptr<FileIO> &base, MACFileIO( const shared_ptr<FileIO> &base,
const shared_ptr<Cipher> &cipher, const FSConfigPtr &cfg );
const CipherKey &key, int blockSize,
int macBytes, int randBytes,
bool warnOnlyMode );
MACFileIO(); MACFileIO();
virtual ~MACFileIO(); virtual ~MACFileIO();
@ -53,8 +50,6 @@ public:
virtual bool isWritable() const; virtual bool isWritable() const;
virtual void allowHoles( bool allow );
private: private:
virtual ssize_t readOneBlock( const IORequest &req ) const; virtual ssize_t readOneBlock( const IORequest &req ) const;
virtual bool writeOneBlock( const IORequest &req ); virtual bool writeOneBlock( const IORequest &req );

View File

@ -47,7 +47,7 @@ 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 5:0:2 libencfs_la_LDFLAGS = -version-info 6: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_SERIALIZATION_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_SYSTEM_LIB@
@ -101,6 +101,7 @@ encfsctl_SOURCES = \
noinst_HEADERS = \ noinst_HEADERS = \
base64.h \ base64.h \
boost-versioning.h \
BlockFileIO.h \ BlockFileIO.h \
BlockNameIO.h \ BlockNameIO.h \
CipherFileIO.h \ CipherFileIO.h \

View File

@ -173,8 +173,9 @@ int TimedPBKDF2(const char *pass, int passlen,
// We support both 2:0 and 1:0, hence current:revision:age = 2:0:1 // We support both 2:0 and 1:0, hence current:revision:age = 2:0:1
// - 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
static Interface BlowfishInterface( "ssl/blowfish", 2, 2, 1 ); // - Version 3:0 adds a new IV mechanism
static Interface AESInterface( "ssl/aes", 2, 2, 1 ); static Interface BlowfishInterface( "ssl/blowfish", 3, 0, 2 );
static Interface AESInterface( "ssl/aes", 3, 0, 2 );
#if defined(HAVE_EVP_BF) #if defined(HAVE_EVP_BF)
@ -399,13 +400,6 @@ CipherKey SSL_Cipher::newKey(const char *password, int passwdLength,
int &iterationCount, long desiredDuration, int &iterationCount, long desiredDuration,
const unsigned char *salt, int saltLen) const unsigned char *salt, int saltLen)
{ {
const EVP_MD *md = EVP_sha1();
if(!md)
{
rError("Unknown digest SHA1");
return CipherKey();
}
shared_ptr<SSLKey> key( new SSLKey( _keySize, _ivLength) ); shared_ptr<SSLKey> key( new SSLKey( _keySize, _ivLength) );
if(iterationCount == 0) if(iterationCount == 0)
@ -441,13 +435,6 @@ CipherKey SSL_Cipher::newKey(const char *password, int passwdLength,
CipherKey SSL_Cipher::newKey(const char *password, int passwdLength) CipherKey SSL_Cipher::newKey(const char *password, int passwdLength)
{ {
const EVP_MD *md = EVP_sha1();
if(!md)
{
rError("Unknown digest SHA1");
return CipherKey();
}
shared_ptr<SSLKey> key( new SSLKey( _keySize, _ivLength) ); shared_ptr<SSLKey> key( new SSLKey( _keySize, _ivLength) );
int bytes = 0; int bytes = 0;
@ -545,7 +532,7 @@ static uint64_t _checksum_64( SSLKey *key,
HMAC_Final( &key->mac_ctx, md, &mdLen ); HMAC_Final( &key->mac_ctx, md, &mdLen );
rAssert(mdLen != 0); rAssert(mdLen >= 8);
// chop this down to a 64bit value.. // chop this down to a 64bit value..
unsigned char h[8] = {0,0,0,0,0,0,0,0}; unsigned char h[8] = {0,0,0,0,0,0,0,0};
@ -690,8 +677,45 @@ int SSL_Cipher::cipherBlockSize() const
return EVP_CIPHER_block_size( _blockCipher ); return EVP_CIPHER_block_size( _blockCipher );
} }
void SSL_Cipher::setIVec( unsigned char *ivec, unsigned int 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)
{
memcpy( ivec, IVData(key), _ivLength );
unsigned char md[EVP_MAX_MD_SIZE];
unsigned int mdLen = EVP_MAX_MD_SIZE;
for(int i=0; i<8; ++i)
{
md[i] = (unsigned char)(seed & 0xff);
seed >>= 8;
}
// combine ivec and seed with HMAC
HMAC_Init_ex( &key->mac_ctx, 0, 0, 0, 0 );
HMAC_Update( &key->mac_ctx, ivec, _ivLength );
HMAC_Update( &key->mac_ctx, md, 8 );
HMAC_Final( &key->mac_ctx, md, &mdLen );
rAssert(mdLen >= _ivLength);
memcpy( ivec, md, _ivLength );
} else
{
setIVec_old(ivec, seed, key);
}
}
/** For backward compatibility.
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
decrypting the file).
*/
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) /* These multiplication constants chosen as they represent (non optimal)
Golumb rulers, the idea being to spread around the information in the Golumb rulers, the idea being to spread around the information in the

View File

@ -137,8 +137,12 @@ public:
// hack to help with static builds // hack to help with static builds
static bool Enabled(); static bool Enabled();
private: private:
void setIVec( unsigned char *ivec, unsigned int seed, void setIVec( unsigned char *ivec, uint64_t seed,
const shared_ptr<SSLKey> &key ) const; const shared_ptr<SSLKey> &key ) const;
// deprecated - for backward compatibility
void setIVec_old( unsigned char *ivec, unsigned int seed,
const shared_ptr<SSLKey> &key ) const;
}; };

View File

@ -25,6 +25,8 @@
#include "Cipher.h" #include "Cipher.h"
#include "Context.h" #include "Context.h"
#include "FileNode.h"
#include "DirNode.h"
#include <rlog/rlog.h> #include <rlog/rlog.h>
#include <rlog/StdioNode.h> #include <rlog/StdioNode.h>
@ -174,8 +176,8 @@ static int showInfo( int argc, char **argv )
if( !checkDir( rootDir )) if( !checkDir( rootDir ))
return EXIT_FAILURE; return EXIT_FAILURE;
EncFSConfig config; boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
ConfigType type = readConfig( rootDir, &config ); ConfigType type = readConfig( rootDir, config );
// show information stored in config.. // show information stored in config..
switch(type) switch(type)
@ -192,24 +194,24 @@ 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) // xgroup(diag)
cout << "\n" << autosprintf(_("Version 5 configuration; " cout << "\n" << autosprintf(_("Version 5 configuration; "
"created by %s (revision %i)\n"), config.creator.c_str(), "created by %s (revision %i)\n"), config->creator.c_str(),
config.subVersion); config->subVersion);
break; break;
case Config_V6: case Config_V6:
// xgroup(diag) // xgroup(diag)
cout << "\n" << autosprintf(_("Version 6 configuration; " cout << "\n" << autosprintf(_("Version 6 configuration; "
"created by %s (revision %i)\n"), config.creator.c_str(), "created by %s (revision %i)\n"), config->creator.c_str(),
config.subVersion); config->subVersion);
break; break;
} }
@ -698,8 +700,8 @@ static int do_chpasswd( bool useStdin, int argc, char **argv )
if( !checkDir( rootDir )) if( !checkDir( rootDir ))
return EXIT_FAILURE; return EXIT_FAILURE;
EncFSConfig config; boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
ConfigType cfgType = readConfig( rootDir, &config ); ConfigType cfgType = readConfig( rootDir, config );
if(cfgType == Config_None) if(cfgType == Config_None)
{ {
@ -709,23 +711,23 @@ static int do_chpasswd( bool useStdin, int argc, char **argv )
// instanciate proper cipher // instanciate proper cipher
shared_ptr<Cipher> cipher = Cipher::New( shared_ptr<Cipher> cipher = Cipher::New(
config.cipherIface, config.keySize ); 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->cipherIface.name().c_str());
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// ask for existing password // ask for existing password
cout << _("Enter current Encfs password\n"); cout << _("Enter current Encfs password\n");
CipherKey userKey = config.getUserKey( useStdin ); CipherKey userKey = config->getUserKey( 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( config->getKeyData(), userKey );
if(!volumeKey) if(!volumeKey)
{ {
@ -737,12 +739,12 @@ static int do_chpasswd( bool useStdin, int argc, char **argv )
userKey.reset(); userKey.reset();
cout << _("Enter new Encfs password\n"); cout << _("Enter new Encfs password\n");
// reinitialize salt and iteration count // reinitialize salt and iteration count
config.kdfIterations = 0; // generate new config->kdfIterations = 0; // generate new
if( useStdin ) if( useStdin )
userKey = config.getUserKey( true ); userKey = config->getUserKey( true );
else else
userKey = config.getNewUserKey(); userKey = config->getNewUserKey();
// 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;
@ -755,10 +757,10 @@ static int do_chpasswd( bool useStdin, int argc, char **argv )
cipher->writeKey( volumeKey, keyBuf, userKey ); cipher->writeKey( volumeKey, keyBuf, userKey );
userKey.reset(); userKey.reset();
config.assignKeyData( keyBuf, encodedKeySize ); config->assignKeyData( keyBuf, encodedKeySize );
delete[] keyBuf; delete[] keyBuf;
if(saveConfig( cfgType, rootDir, &config )) if(saveConfig( cfgType, 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");

View File

@ -257,23 +257,24 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
} }
} }
shared_ptr<DirNode::Config> dnConfig( new DirNode::Config ); FSConfigPtr fsCfg = FSConfigPtr(new FSConfig);
dnConfig->cipher = cipher; fsCfg->cipher = cipher;
dnConfig->key = key; fsCfg->key = key;
dnConfig->blockSize = FSBlockSize; fsCfg->config.reset(new EncFSConfig);
fsCfg->config->blockSize = 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";
{ {
dnConfig->inactivityTimer = false; fsCfg->opts.reset(new EncFS_Opts);
dnConfig->blockMACBytes = 0; fsCfg->opts->idleTracking = false;
dnConfig->blockMACRandBytes = 0; fsCfg->config->uniqueIV = false;
dnConfig->uniqueIV = false;
dnConfig->nameCoding = shared_ptr<NameIO>( new StreamNameIO(
StreamNameIO::CurrentInterface(), cipher, key ) );
dnConfig->nameCoding->setChainedNameIV( true );
DirNode dirNode( NULL, TEST_ROOTDIR, dnConfig ); fsCfg->nameCoding.reset( new StreamNameIO(
StreamNameIO::CurrentInterface(), cipher, key ) );
fsCfg->nameCoding->setChainedNameIV( true );
DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg );
if(!testNameCoding( dirNode, verbose )) if(!testNameCoding( dirNode, verbose ))
return false; return false;
@ -282,16 +283,14 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
if(verbose) if(verbose)
cerr << "Testing name encode/decode (block coding w/ IV chaining)\n"; cerr << "Testing name encode/decode (block coding w/ IV chaining)\n";
{ {
dnConfig->inactivityTimer = false; fsCfg->opts->idleTracking = false;
dnConfig->blockMACBytes = 0; fsCfg->config->uniqueIV = false;
dnConfig->blockMACRandBytes = 0; fsCfg->nameCoding.reset( new BlockNameIO(
dnConfig->uniqueIV = false;
dnConfig->nameCoding = shared_ptr<NameIO>( new BlockNameIO(
BlockNameIO::CurrentInterface(), cipher, key, BlockNameIO::CurrentInterface(), cipher, key,
cipher->cipherBlockSize() ) ); cipher->cipherBlockSize() ) );
dnConfig->nameCoding->setChainedNameIV( true ); fsCfg->nameCoding->setChainedNameIV( true );
DirNode dirNode( NULL, TEST_ROOTDIR, dnConfig ); DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg );
if(!testNameCoding( dirNode, verbose )) if(!testNameCoding( dirNode, verbose ))
return false; return false;
@ -301,16 +300,12 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
{ {
{ {
// test stream mode, this time without IV chaining // test stream mode, this time without IV chaining
dnConfig->inactivityTimer = false; fsCfg->nameCoding =
dnConfig->blockMACBytes = 0;
dnConfig->blockMACRandBytes = 0;
dnConfig->uniqueIV = false;
dnConfig->nameCoding =
shared_ptr<NameIO>( new StreamNameIO( shared_ptr<NameIO>( new StreamNameIO(
StreamNameIO::CurrentInterface(), cipher, key ) ); StreamNameIO::CurrentInterface(), cipher, key ) );
dnConfig->nameCoding->setChainedNameIV( false ); fsCfg->nameCoding->setChainedNameIV( false );
DirNode dirNode( NULL, TEST_ROOTDIR, dnConfig ); DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg );
if(!testNameCoding( dirNode, verbose )) if(!testNameCoding( dirNode, verbose ))
return false; return false;
@ -318,16 +313,12 @@ bool runTests(const shared_ptr<Cipher> &cipher, bool verbose)
{ {
// test block mode, this time without IV chaining // test block mode, this time without IV chaining
dnConfig->inactivityTimer = false; fsCfg->nameCoding = shared_ptr<NameIO>( new BlockNameIO(
dnConfig->blockMACBytes = 0;
dnConfig->blockMACRandBytes = 0;
dnConfig->uniqueIV = false;
dnConfig->nameCoding = shared_ptr<NameIO>( new BlockNameIO(
BlockNameIO::CurrentInterface(), cipher, key, BlockNameIO::CurrentInterface(), cipher, key,
cipher->cipherBlockSize() ) ); cipher->cipherBlockSize() ) );
dnConfig->nameCoding->setChainedNameIV( false ); fsCfg->nameCoding->setChainedNameIV( false );
DirNode dirNode( NULL, TEST_ROOTDIR, dnConfig ); DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg );
if(!testNameCoding( dirNode, verbose )) if(!testNameCoding( dirNode, verbose ))
return false; return false;

View File

@ -1,9 +1,8 @@
EXTRA_DIST = \ EXTRA_DIST = \
codeset.m4 inttypes_h.m4 lib-link.m4 printf-posix.m4 \ acx_pthread.m4 intl.m4 lib-ld.m4 ltsugar.m4 size_max.m4 \
ulonglong.m4 gettext.m4 inttypes.m4 lib-prefix.m4 \ codeset.m4 intldir.m4 lib-link.m4 ltversion.m4 stdint_h.m4 \
progtest.m4 wchar_t.m4 glibc21.m4 inttypes-pri.m4 \ gettext.m4 intlmacosx.m4 lib-prefix.m4 lt~obsolete.m4 uintmax_t.m4 \
longdouble.m4 signed.m4 wint_t.m4 iconv.m4 isc-posix.m4 \ glibc2.m4 intmax.m4 libtool.m4 nls.m4 visibility.m4 \
longlong.m4 size_max.m4 xsize.m4 intdiv0.m4 lcmessage.m4 \ glibc21.m4 inttypes-pri.m4 lock.m4 po.m4 wchar_t.m4 \
nls.m4 stdint_h.m4 intmax.m4 lib-ld.m4 po.m4 uintmax_t.m4 \ iconv.m4 inttypes_h.m4 longlong.m4 printf-posix.m4 wint_t.m4 \
acx_pthread.m4 intdiv0.m4 lcmessage.m4 ltoptions.m4 progtest.m4 xsize.m4

View File

@ -4,7 +4,7 @@
make dist make dist
# create tar archive and signature # create tar archive and signature
tarArchive=@PACKAGE@-@VERSION@-@RELEASE@.tgz tarArchive=@PACKAGE@-@VERSION@.tgz
mv @PACKAGE@-@VERSION@.tar.gz $tarArchive mv @PACKAGE@-@VERSION@.tar.gz $tarArchive
# let the user know why they're being asked for a passpharse # let the user know why they're being asked for a passpharse
echo "Signing tar archive - enter GPG password"; echo "Signing tar archive - enter GPG password";