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;
if(haveHeader)
{
IORequest tmpReq = req; IORequest tmpReq = req;
if(haveHeader)
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>
@ -34,17 +35,9 @@ 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,
@ -182,9 +93,22 @@ struct EncFS_Opts
} }
}; };
/*
Read existing config file. Looks for any supported configuration version.
*/
ConfigType readConfig( const std::string &rootDir,
const boost::shared_ptr<EncFSConfig> &config );
/*
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,7 +677,44 @@ 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
{
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 const shared_ptr<SSLKey> &key) const
{ {
/* These multiplication constants chosen as they represent (non optimal) /* These multiplication constants chosen as they represent (non optimal)

View File

@ -137,7 +137,11 @@ 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;
// deprecated - for backward compatibility
void setIVec_old( unsigned char *ivec, unsigned int seed,
const shared_ptr<SSLKey> &key ) const; 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";