diff --git a/base/ConfigReader.cpp b/base/ConfigReader.cpp index a623b67..18378f4 100644 --- a/base/ConfigReader.cpp +++ b/base/ConfigReader.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -36,90 +36,75 @@ using std::string; namespace encfs { -ConfigReader::ConfigReader() -{ -} +ConfigReader::ConfigReader() {} -ConfigReader::~ConfigReader() -{ -} +ConfigReader::~ConfigReader() {} // read the entire file into a ConfigVar instance and then use that to decode // into mapped variables. -bool ConfigReader::load(const char *fileName) -{ +bool ConfigReader::load(const char *fileName) { struct stat stbuf; - memset( &stbuf, 0, sizeof(struct stat)); - if( lstat( fileName, &stbuf ) != 0) - return false; + memset(&stbuf, 0, sizeof(struct stat)); + if (lstat(fileName, &stbuf) != 0) return false; int size = stbuf.st_size; - int fd = open( fileName, O_RDONLY ); - if(fd < 0) - return false; + int fd = open(fileName, O_RDONLY); + if (fd < 0) return false; char *buf = new char[size]; - int res = ::read( fd, buf, size ); - close( fd ); + int res = ::read(fd, buf, size); + close(fd); - if( res != size ) - { - LOG(WARNING) << "Partial read of config file, expecting " - << size << " bytes, got " << res; + if (res != size) { + LOG(WARNING) << "Partial read of config file, expecting " << size + << " bytes, got " << res; delete[] buf; return false; } ConfigVar in; - in.write( (byte *)buf, size ); + in.write((byte *)buf, size); delete[] buf; - return loadFromVar( in ); + return loadFromVar(in); } -bool ConfigReader::loadFromVar(ConfigVar &in) -{ +bool ConfigReader::loadFromVar(ConfigVar &in) { in.resetOffset(); // parse. int numEntries = in.readInt(); - for(int i=0; i> key >> value; - if(key.length() == 0) - { + if (key.length() == 0) { LOG(ERROR) << "Invalid key encoding in buffer"; return false; } - ConfigVar newVar( value ); - vars.insert( make_pair( key, newVar ) ); + ConfigVar newVar(value); + vars.insert(make_pair(key, newVar)); } return true; } -bool ConfigReader::save(const char *fileName) const -{ +bool ConfigReader::save(const char *fileName) const { // write everything to a ConfigVar, then output to disk ConfigVar out = toVar(); - int fd = ::open( fileName, O_RDWR | O_CREAT, 0640 ); - if(fd >= 0) - { - int retVal = ::write( fd, out.buffer(), out.size() ); - close( fd ); - if(retVal != out.size()) - { + int fd = ::open(fileName, O_RDWR | O_CREAT, 0640); + if (fd >= 0) { + int retVal = ::write(fd, out.buffer(), out.size()); + close(fd); + if (retVal != out.size()) { LOG(ERROR) << "Error writing to config file " << fileName; return false; } - } else - { + } else { LOG(ERROR) << "Unable to open or create file " << fileName; return false; } @@ -127,36 +112,32 @@ bool ConfigReader::save(const char *fileName) const return true; } -ConfigVar ConfigReader::toVar() const -{ +ConfigVar ConfigReader::toVar() const { // write everything to a ConfigVar, then output to disk ConfigVar out; - out.writeInt( vars.size() ); + out.writeInt(vars.size()); map::const_iterator it; - for(it = vars.begin(); it != vars.end(); ++it) - { - out.writeInt( it->first.size() ); - out.write( (byte*)it->first.data(), it->first.size() ); - out.writeInt( it->second.size() ); - out.write( (byte*)it->second.buffer(), it->second.size() ); + for (it = vars.begin(); it != vars.end(); ++it) { + out.writeInt(it->first.size()); + out.write((byte *)it->first.data(), it->first.size()); + out.writeInt(it->second.size()); + out.write((byte *)it->second.buffer(), it->second.size()); } return out; } -ConfigVar ConfigReader::operator[] ( const std::string &varName ) const -{ +ConfigVar ConfigReader::operator[](const std::string &varName) const { // read only - map::const_iterator it = vars.find( varName ); - if( it == vars.end() ) + map::const_iterator it = vars.find(varName); + if (it == vars.end()) return ConfigVar(); else return it->second; } -ConfigVar &ConfigReader::operator[] ( const std::string &varName ) -{ - return vars[ varName ]; +ConfigVar &ConfigReader::operator[](const std::string &varName) { + return vars[varName]; } } // namespace encfs diff --git a/base/ConfigReader.h b/base/ConfigReader.h index 95ee22f..c53fe6d 100644 --- a/base/ConfigReader.h +++ b/base/ConfigReader.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + #ifndef _ConfigReader_incl_ #define _ConfigReader_incl_ @@ -45,26 +45,24 @@ namespace encfs { ConfigReader cfg; cfg["cipher"] << cipher->interface(); */ -class ConfigReader -{ -public: - ConfigReader(); - ~ConfigReader(); +class ConfigReader { + public: + ConfigReader(); + ~ConfigReader(); - bool load(const char *fileName); - bool save(const char *fileName) const; + bool load(const char *fileName); + bool save(const char *fileName) const; - ConfigVar toVar() const; - bool loadFromVar( ConfigVar &var ); + ConfigVar toVar() const; + bool loadFromVar(ConfigVar &var); - ConfigVar operator[](const std::string &varName) const; - ConfigVar &operator[](const std::string &varName); + ConfigVar operator[](const std::string &varName) const; + ConfigVar &operator[](const std::string &varName); -private: - std::map vars; + private: + std::map vars; }; - } // namespace encfs #endif diff --git a/base/ConfigVar.cpp b/base/ConfigVar.cpp index 94b7b06..71c7eb5 100644 --- a/base/ConfigVar.cpp +++ b/base/ConfigVar.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -27,39 +27,22 @@ namespace encfs { #ifndef MIN -inline int MIN(int a, int b) -{ - return (a < b) ? a : b; -} +inline int MIN(int a, int b) { return (a < b) ? a : b; } #endif +ConfigVar::ConfigVar() : pd(new ConfigVarData) { pd->offset = 0; } -ConfigVar::ConfigVar() - : pd( new ConfigVarData ) -{ - pd->offset = 0; -} - -ConfigVar::ConfigVar(const std::string &buf) - : pd( new ConfigVarData ) -{ +ConfigVar::ConfigVar(const std::string &buf) : pd(new ConfigVarData) { pd->buffer = buf; pd->offset = 0; } -ConfigVar::ConfigVar(const ConfigVar &src) -{ - pd = src.pd; -} +ConfigVar::ConfigVar(const ConfigVar &src) { pd = src.pd; } -ConfigVar::~ConfigVar() -{ - pd.reset(); -} +ConfigVar::~ConfigVar() { pd.reset(); } -ConfigVar & ConfigVar::operator = (const ConfigVar &src) -{ - if(src.pd == pd) +ConfigVar &ConfigVar::operator=(const ConfigVar &src) { + if (src.pd == pd) return *this; else pd = src.pd; @@ -67,31 +50,23 @@ ConfigVar & ConfigVar::operator = (const ConfigVar &src) return *this; } -void ConfigVar::resetOffset() -{ - pd->offset = 0; -} +void ConfigVar::resetOffset() { pd->offset = 0; } -int ConfigVar::read(byte *buffer_, int bytes) const -{ - int toCopy = MIN( bytes, pd->buffer.size() - pd->offset ); +int ConfigVar::read(byte *buffer_, int bytes) const { + int toCopy = MIN(bytes, pd->buffer.size() - pd->offset); - if(toCopy > 0) - memcpy( buffer_, pd->buffer.data() + pd->offset, toCopy ); + if (toCopy > 0) memcpy(buffer_, pd->buffer.data() + pd->offset, toCopy); pd->offset += toCopy; return toCopy; } -int ConfigVar::write(const byte *data, int bytes) -{ - if(pd->buffer.size() == (unsigned int)pd->offset) - { - pd->buffer.append( (const char *)data, bytes ); - } else - { - pd->buffer.insert( pd->offset, (const char *)data, bytes ); +int ConfigVar::write(const byte *data, int bytes) { + if (pd->buffer.size() == (unsigned int)pd->offset) { + pd->buffer.append((const char *)data, bytes); + } else { + pd->buffer.insert(pd->offset, (const char *)data, bytes); } pd->offset += bytes; @@ -99,31 +74,19 @@ int ConfigVar::write(const byte *data, int bytes) return bytes; } -int ConfigVar::size() const -{ - return pd->buffer.size(); -} +int ConfigVar::size() const { return pd->buffer.size(); } -const char *ConfigVar::buffer() const -{ - return pd->buffer.data(); -} +const char *ConfigVar::buffer() const { return pd->buffer.data(); } -int ConfigVar::at() const -{ - return pd->offset; -} +int ConfigVar::at() const { return pd->offset; } -void ConfigVar::writeString(const char *data, int bytes) -{ - writeInt( bytes ); - write( (const byte *)data, bytes ); +void ConfigVar::writeString(const char *data, int bytes) { + writeInt(bytes); + write((const byte *)data, bytes); } - // convert integer to BER encoded integer -void ConfigVar::writeInt(int val) -{ +void ConfigVar::writeInt(int val) { // we can represent 7 bits per char output, so a 32bit number may take up // to 5 bytes. // first byte: 0x0000007f 0111,1111 @@ -133,7 +96,7 @@ void ConfigVar::writeInt(int val) // fifth byte: 0xf0000000 1111,0000 byte digit[5]; - digit[4] = (byte)((val & 0x0000007f)); + digit[4] = (byte)((val & 0x0000007f)); digit[3] = 0x80 | (byte)((val & 0x00003f80) >> 7); digit[2] = 0x80 | (byte)((val & 0x001fc000) >> 14); digit[1] = 0x80 | (byte)((val & 0x0fe00000) >> 21); @@ -142,110 +105,96 @@ void ConfigVar::writeInt(int val) // find the starting point - we only need to output starting at the most // significant non-zero digit.. int start = 0; - while(digit[start] == 0x80) - ++start; + while (digit[start] == 0x80) ++start; - write( digit + start, 5-start ); + write(digit + start, 5 - start); } -int ConfigVar::readInt() const -{ - const byte * buf = (const byte *)buffer(); +int ConfigVar::readInt() const { + const byte *buf = (const byte *)buffer(); int bytes = this->size(); int offset = at(); int value = 0; bool highBitSet; - rAssert( offset < bytes ); + rAssert(offset < bytes); - do - { + do { byte tmp = buf[offset++]; highBitSet = tmp & 0x80; value = (value << 7) | (int)(tmp & 0x7f); - } while(highBitSet && offset < bytes); + } while (highBitSet && offset < bytes); pd->offset = offset; // should never end up with a negative number.. - rAssert( value >= 0 ); + rAssert(value >= 0); return value; } -int ConfigVar::readInt( int defaultValue ) const -{ +int ConfigVar::readInt(int defaultValue) const { int bytes = this->size(); int offset = at(); - if(offset >= bytes) + if (offset >= bytes) return defaultValue; else return readInt(); } -bool ConfigVar::readBool( bool defaultValue ) const -{ - int tmp = readInt( defaultValue ? 1 : 0 ); +bool ConfigVar::readBool(bool defaultValue) const { + int tmp = readInt(defaultValue ? 1 : 0); return (tmp != 0); } -ConfigVar & operator << (ConfigVar &src, bool value) -{ - src.writeInt( value ? 1 : 0 ); +ConfigVar &operator<<(ConfigVar &src, bool value) { + src.writeInt(value ? 1 : 0); return src; } -ConfigVar & operator << (ConfigVar &src, int var) -{ - src.writeInt( var ); +ConfigVar &operator<<(ConfigVar &src, int var) { + src.writeInt(var); return src; } -ConfigVar & operator << (ConfigVar &src, const std::string &str) -{ - src.writeString( str.data(), str.length() ); +ConfigVar &operator<<(ConfigVar &src, const std::string &str) { + src.writeString(str.data(), str.length()); return src; } -const ConfigVar & operator >> (const ConfigVar &src, bool &result) -{ +const ConfigVar &operator>>(const ConfigVar &src, bool &result) { int tmp = src.readInt(); result = (tmp != 0); return src; } -const ConfigVar & operator >> (const ConfigVar &src, int &result) -{ +const ConfigVar &operator>>(const ConfigVar &src, int &result) { result = src.readInt(); return src; } -const ConfigVar & operator >> (const ConfigVar &src, std::string &result) -{ +const ConfigVar &operator>>(const ConfigVar &src, std::string &result) { int length = src.readInt(); LOG_IF(WARNING, length <= 0) << "Invalid config length " << length; int readLen; byte tmpBuf[32]; - if(length > (int)sizeof(tmpBuf)) - { + if (length > (int)sizeof(tmpBuf)) { byte *ptr = new byte[length]; - readLen = src.read( ptr, length ); - result.assign( (char*)ptr, length ); + readLen = src.read(ptr, length); + result.assign((char *)ptr, length); delete[] ptr; - } else - { - readLen = src.read( tmpBuf, length ); - result.assign( (char*)tmpBuf, length ); + } else { + readLen = src.read(tmpBuf, length); + result.assign((char *)tmpBuf, length); } - if(readLen != length) - { - VLOG(1) << "string encoded as size " << length - << " bytes, read " << readLen; + if (readLen != length) { + VLOG(1) << "string encoded as size " << length << " bytes, read " + << readLen; } rAssert(readLen == length); diff --git a/base/ConfigVar.h b/base/ConfigVar.h index 1d431db..0a7757f 100644 --- a/base/ConfigVar.h +++ b/base/ConfigVar.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -27,60 +27,57 @@ namespace encfs { -class ConfigVar -{ - struct ConfigVarData - { - std::string buffer; - int offset; - }; +class ConfigVar { + struct ConfigVarData { + std::string buffer; + int offset; + }; - shared_ptr pd; + shared_ptr pd; -public: - ConfigVar(); - ConfigVar(const std::string &buffer); - ConfigVar(const ConfigVar &src); - ~ConfigVar(); + public: + ConfigVar(); + ConfigVar(const std::string &buffer); + ConfigVar(const ConfigVar &src); + ~ConfigVar(); - ConfigVar & operator = (const ConfigVar &src); + ConfigVar &operator=(const ConfigVar &src); - // reset read/write offset.. - void resetOffset(); + // reset read/write offset.. + void resetOffset(); - // read bytes - int read(byte *buffer, int size) const; + // read bytes + int read(byte *buffer, int size) const; - // write bytes.. - int write(const byte *data, int size); + // write bytes.. + int write(const byte *data, int size); - int readInt() const; - int readInt( int defaultValue ) const; - void writeInt(int value); + int readInt() const; + int readInt(int defaultValue) const; + void writeInt(int value); - bool readBool( bool defaultValue ) const; + bool readBool(bool defaultValue) const; - void writeString(const char *data, int size); + void writeString(const char *data, int size); - // return amount of data in var - int size() const; - // return data pointer - returns front of data pointer, not the current - // position. - const char *buffer() const; + // return amount of data in var + int size() const; + // return data pointer - returns front of data pointer, not the current + // position. + const char *buffer() const; - // return current position in data() buffer. - int at() const; + // return current position in data() buffer. + int at() const; }; -ConfigVar & operator << (ConfigVar &, bool); -ConfigVar & operator << (ConfigVar &, int); -ConfigVar & operator << (ConfigVar &, const std::string &str); +ConfigVar &operator<<(ConfigVar &, bool); +ConfigVar &operator<<(ConfigVar &, int); +ConfigVar &operator<<(ConfigVar &, const std::string &str); -const ConfigVar & operator >> (const ConfigVar &, bool &); -const ConfigVar & operator >> (const ConfigVar &, int &); -const ConfigVar & operator >> (const ConfigVar &, std::string &str); +const ConfigVar &operator>>(const ConfigVar &, bool &); +const ConfigVar &operator>>(const ConfigVar &, int &); +const ConfigVar &operator>>(const ConfigVar &, std::string &str); } // namespace encfs #endif - diff --git a/base/Error.cpp b/base/Error.cpp index e901c8e..898279d 100644 --- a/base/Error.cpp +++ b/base/Error.cpp @@ -2,9 +2,6 @@ namespace encfs { -Error::Error(const char *msg) - : runtime_error(msg) -{ -} +Error::Error(const char *msg) : runtime_error(msg) {} } // namespace encfs diff --git a/base/Error.h b/base/Error.h index ce76f0b..08fd466 100644 --- a/base/Error.h +++ b/base/Error.h @@ -6,24 +6,21 @@ namespace encfs { -class Error : public std::runtime_error -{ -public: +class Error : public std::runtime_error { + public: Error(const char *msg); }; #define STR(X) #X -#define rAssert( cond ) \ - do { \ - if( (cond) == false) \ - { LOG(ERROR) << "Assert failed: " << STR(cond); \ - throw Error(STR(cond)); \ - } \ - } while(0) - +#define rAssert(cond) \ + do { \ + if ((cond) == false) { \ + LOG(ERROR) << "Assert failed: " << STR(cond); \ + throw Error(STR(cond)); \ + } \ + } while (0) } // namespace encfs #endif - diff --git a/base/Interface.cpp b/base/Interface.cpp index d1b9b00..f7229cd 100644 --- a/base/Interface.cpp +++ b/base/Interface.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + #include "base/Interface.h" #include "base/ConfigVar.h" @@ -27,26 +27,22 @@ namespace encfs { -std::ostream& operator << (std::ostream& out, const Interface &iface) -{ - out << iface.name() << "(" << iface.major() - << ":" << iface.minor() << ":" << iface.age() << ")"; +std::ostream &operator<<(std::ostream &out, const Interface &iface) { + out << iface.name() << "(" << iface.major() << ":" << iface.minor() << ":" + << iface.age() << ")"; return out; } -bool implements(const Interface &A, const Interface &B) -{ +bool implements(const Interface &A, const Interface &B) { VLOG(1) << "checking if " << A << " implements " << B; - if( A.name() != B.name() ) - return false; + if (A.name() != B.name()) return false; int currentDiff = A.major() - B.major(); - return ( currentDiff >= 0 && currentDiff <= (int)A.age() ); + return (currentDiff >= 0 && currentDiff <= (int)A.age()); } -Interface makeInterface(const char *name, int major, int minor, int age) -{ +Interface makeInterface(const char *name, int major, int minor, int age) { Interface iface; iface.set_name(name); iface.set_major(major); @@ -55,15 +51,13 @@ Interface makeInterface(const char *name, int major, int minor, int age) return iface; } -ConfigVar & operator << (ConfigVar &dst, const Interface &iface) -{ +ConfigVar &operator<<(ConfigVar &dst, const Interface &iface) { dst << iface.name() << (int)iface.major() << (int)iface.minor() << (int)iface.age(); return dst; } -const ConfigVar & operator >> (const ConfigVar &src, Interface &iface) -{ +const ConfigVar &operator>>(const ConfigVar &src, Interface &iface) { src >> *iface.mutable_name(); int major, minor, age; src >> major >> minor >> age; @@ -73,13 +67,10 @@ const ConfigVar & operator >> (const ConfigVar &src, Interface &iface) return src; } -bool operator != (const Interface &a, const Interface &b) -{ - if (a.major() != b.major()) - return true; +bool operator!=(const Interface &a, const Interface &b) { + if (a.major() != b.major()) return true; - if (a.minor() != b.minor()) - return true; + if (a.minor() != b.minor()) return true; return false; } diff --git a/base/Interface.h b/base/Interface.h index 1c144c4..d93b1d7 100644 --- a/base/Interface.h +++ b/base/Interface.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -31,16 +31,15 @@ namespace encfs { // This checks the current() version and age() against B.current() for // compatibility. Even if A.implements(B) is true, B > A may also be // true, meaning B is a newer revision of the interface then A. -bool implements( const Interface &a, const Interface &b ); -Interface makeInterface( const char *name, int major, int minor, int age ); +bool implements(const Interface &a, const Interface &b); +Interface makeInterface(const char *name, int major, int minor, int age); // Read operation class ConfigVar; -const ConfigVar & operator >> (const ConfigVar &, Interface &); +const ConfigVar &operator>>(const ConfigVar &, Interface &); -bool operator != (const Interface &a, const Interface &b); +bool operator!=(const Interface &a, const Interface &b); } // namespace encfs #endif - diff --git a/base/Mutex.h b/base/Mutex.h index 7e8df4e..36c26be 100644 --- a/base/Mutex.h +++ b/base/Mutex.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -29,76 +29,58 @@ #warning No thread support. #endif -namespace encfs -{ +namespace encfs { -class Mutex -{ +class Mutex { public: #ifdef CMAKE_USE_PTHREADS_INIT pthread_mutex_t _mutex; - Mutex() { - pthread_mutex_init( &_mutex, 0 ); - } - ~Mutex() { - pthread_mutex_destroy( &_mutex ); - } + Mutex() { pthread_mutex_init(&_mutex, 0); } + ~Mutex() { pthread_mutex_destroy(&_mutex); } #endif void lock(); void unlock(); }; -class Lock -{ -public: - explicit Lock( Mutex &mutex ); +class Lock { + public: + explicit Lock(Mutex &mutex); ~Lock(); // leave the lock as it is. When the Lock wrapper is destroyed, it // will do nothing with the pthread mutex. void leave(); -private: - Lock(const Lock &src); // not allowed - Lock &operator = (const Lock &src); // not allowed + private: + Lock(const Lock &src); // not allowed + Lock &operator=(const Lock &src); // not allowed Mutex *_mutex; }; -inline void Mutex::lock() -{ +inline void Mutex::lock() { #ifdef CMAKE_USE_PTHREADS_INIT - pthread_mutex_lock( &_mutex ); + pthread_mutex_lock(&_mutex); #endif } -inline void Mutex::unlock() -{ +inline void Mutex::unlock() { #ifdef CMAKE_USE_PTHREADS_INIT - pthread_mutex_unlock( &_mutex ); + pthread_mutex_unlock(&_mutex); #endif } -inline Lock::Lock( Mutex &mutex ) - : _mutex( &mutex ) -{ - if (_mutex) - _mutex->lock(); +inline Lock::Lock(Mutex &mutex) : _mutex(&mutex) { + if (_mutex) _mutex->lock(); } -inline Lock::~Lock( ) -{ - if(_mutex) - _mutex->unlock(); +inline Lock::~Lock() { + if (_mutex) _mutex->unlock(); } -inline void Lock::leave() -{ - _mutex = NULL; -} +inline void Lock::leave() { _mutex = NULL; } } // namespace encfs #endif - diff --git a/base/Range.h b/base/Range.h index 1639d6b..647e4fb 100644 --- a/base/Range.h +++ b/base/Range.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + #ifndef _Range_incl_ #define _Range_incl_ @@ -25,26 +25,26 @@ namespace encfs { -class Range -{ - int minVal; - int maxVal; - int increment; -public: - Range(); - Range(int minMax); - Range(int min, int max, int increment); +class Range { + int minVal; + int maxVal; + int increment; - bool allowed(int value) const; + public: + Range(); + Range(int minMax); + Range(int min, int max, int increment); - int closest(int value) const; + bool allowed(int value) const; - int min() const; - int max() const; - int inc() const; + int closest(int value) const; + + int min() const; + int max() const; + int inc() const; }; -inline std::ostream & operator << (std::ostream &st, const Range &r) { +inline std::ostream &operator<<(std::ostream &st, const Range &r) { bool separator = false; for (int size = r.min(); size <= r.max(); size += r.inc()) { if (separator) @@ -56,76 +56,52 @@ inline std::ostream & operator << (std::ostream &st, const Range &r) { return st; } -inline Range::Range(int minMax) -{ - this->minVal = minMax; - this->maxVal = minMax; - this->increment = 1; +inline Range::Range(int minMax) { + this->minVal = minMax; + this->maxVal = minMax; + this->increment = 1; } -inline Range::Range(int min_, int max_, int increment_) -{ - this->minVal = min_; - this->maxVal = max_; - this->increment = increment_; - if(increment == 0) - this->increment = 1; +inline Range::Range(int min_, int max_, int increment_) { + this->minVal = min_; + this->maxVal = max_; + this->increment = increment_; + if (increment == 0) this->increment = 1; } -inline Range::Range() - : minVal(-1) - , maxVal(-1) - , increment(1) -{ -} +inline Range::Range() : minVal(-1), maxVal(-1), increment(1) {} -inline bool Range::allowed(int value) const -{ - if(minVal < 0 && maxVal < 0) - return true; - if(value >= minVal && value <= maxVal) - { - int tmp = value - minVal; - if((tmp % increment) == 0) - return true; - } - return false; -} - -inline int Range::closest(int value) const -{ - if(allowed(value)) - return value; - else - if(value < minVal) - return minVal; - else - if(value > maxVal) - return maxVal; - - // must be inbetween but not matched with increment +inline bool Range::allowed(int value) const { + if (minVal < 0 && maxVal < 0) return true; + if (value >= minVal && value <= maxVal) { int tmp = value - minVal; - // try rounding to the nearest increment.. - tmp += (increment >> 1); - tmp -= (tmp % increment); - - return closest( value + tmp ); + if ((tmp % increment) == 0) return true; + } + return false; } - -inline int Range::min() const -{ + +inline int Range::closest(int value) const { + if (allowed(value)) + return value; + else if (value < minVal) return minVal; -} - -inline int Range::max() const -{ + else if (value > maxVal) return maxVal; + + // must be inbetween but not matched with increment + int tmp = value - minVal; + // try rounding to the nearest increment.. + tmp += (increment >> 1); + tmp -= (tmp % increment); + + return closest(value + tmp); } -inline int Range::inc() const -{ - return increment; -} +inline int Range::min() const { return minVal; } -} // namespace encfs +inline int Range::max() const { return maxVal; } + +inline int Range::inc() const { return increment; } + +} // namespace encfs #endif diff --git a/base/Registry.h b/base/Registry.h index e9182d1..1e81f79 100644 --- a/base/Registry.h +++ b/base/Registry.h @@ -8,34 +8,29 @@ namespace encfs { template -class Registry -{ -public: +class Registry { + public: typedef T *(*FactoryFn)(); struct Data { FactoryFn constructor; typename T::Properties properties; }; - void Register(const char *name, FactoryFn fn, - typename T::Properties properties) - { + void Register(const char *name, FactoryFn fn, + typename T::Properties properties) { Data d; d.constructor = fn; d.properties = properties; data[name] = d; } - T* Create(const char *name) - { + T *Create(const char *name) { auto it = data.find(name); - if (it == data.end()) - return NULL; + if (it == data.end()) return NULL; return (*it->second.constructor)(); } - T* CreateForMatch(const std::string &description) - { + T *CreateForMatch(const std::string &description) { for (auto &it : data) { auto name = it.second.properties.toString(); if (!name.compare(0, description.size(), description)) @@ -54,11 +49,10 @@ public: const typename T::Properties *GetProperties(const char *name) const { auto it = data.find(name); - if (it == data.end()) - return NULL; + if (it == data.end()) return NULL; return &(it->second.properties); } - + const typename T::Properties *GetPropertiesForMatch( const std::string &description) const { for (auto &it : data) { @@ -69,39 +63,32 @@ public: return NULL; } - -private: + private: std::map data; }; template -class Registrar -{ -public: - Registrar(const char *name) - { - BASE::GetRegistry().Register(name, - Registrar::Construct, +class Registrar { + public: + Registrar(const char *name) { + BASE::GetRegistry().Register(name, Registrar::Construct, T::GetProperties()); } - static BASE *Construct() { - return new T(); - } + static BASE *Construct() { return new T(); } }; -#define DECLARE_REGISTERABLE_TYPE(TYPE) \ - static Registry& GetRegistry() +#define DECLARE_REGISTERABLE_TYPE(TYPE) static Registry &GetRegistry() -#define DEFINE_REGISTERABLE_TYPE(TYPE) \ - Registry& TYPE::GetRegistry() { \ - static Registry registry; \ - return registry; \ - } +#define DEFINE_REGISTERABLE_TYPE(TYPE) \ + Registry &TYPE::GetRegistry() { \ + static Registry registry; \ + return registry; \ + } #define REGISTER_CLASS(DERIVED, BASE) \ - static Registrar registrar_ ## DERIVED ## _ ## BASE (#DERIVED) + static Registrar registrar_##DERIVED##_##BASE(#DERIVED) } // namespace encfs -#endif // REGISTRY_H +#endif // REGISTRY_H diff --git a/base/XmlReader.cpp b/base/XmlReader.cpp index 704aa1e..458306b 100644 --- a/base/XmlReader.cpp +++ b/base/XmlReader.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -38,90 +38,70 @@ namespace encfs { -XmlValue::~XmlValue() -{ -} +XmlValue::~XmlValue() {} -XmlValuePtr XmlValue::operator[] (const char *path) const -{ - return find(path); -} +XmlValuePtr XmlValue::operator[](const char *path) const { return find(path); } -XmlValuePtr XmlValue::find(const char *path) const -{ +XmlValuePtr XmlValue::find(const char *path) const { LOG_FIRST_N(ERROR, 1) << "in XmlValue::find( " << path << ")"; return XmlValuePtr(); } -bool XmlValue::read(const char *path, std::string *out) const -{ +bool XmlValue::read(const char *path, std::string *out) const { XmlValuePtr value = find(path); - if (!value) - return false; + if (!value) return false; *out = value->text(); return true; } -bool XmlValue::read(const char *path, int *out) const -{ +bool XmlValue::read(const char *path, int *out) const { XmlValuePtr value = find(path); - if (!value) - return false; + if (!value) return false; *out = atoi(value->text().c_str()); return true; } -bool XmlValue::read(const char *path, long *out) const -{ +bool XmlValue::read(const char *path, long *out) const { XmlValuePtr value = find(path); - if (!value) - return false; + if (!value) return false; *out = atol(value->text().c_str()); return true; } -bool XmlValue::read(const char *path, double *out) const -{ +bool XmlValue::read(const char *path, double *out) const { XmlValuePtr value = find(path); - if (!value) - return false; + if (!value) return false; *out = atof(value->text().c_str()); return true; } -bool XmlValue::read(const char *path, bool *out) const -{ +bool XmlValue::read(const char *path, bool *out) const { XmlValuePtr value = find(path); - if (!value) - return false; + if (!value) return false; *out = atoi(value->text().c_str()); return true; } -bool XmlValue::readB64(const char *path, byte *data, int length) const -{ +bool XmlValue::readB64(const char *path, byte *data, int length) const { XmlValuePtr value = find(path); - if (!value) - return false; - + if (!value) return false; + std::string s = value->text(); s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end()); - s.erase(s.find_last_not_of("=")+1); + s.erase(s.find_last_not_of("=") + 1); int decodedSize = B64ToB256Bytes(s.size()); - if (decodedSize != length) - { - LOG(ERROR) << "decoding bytes len " << s.size() - << ", expecting output len " << length - << ", got " << decodedSize; + if (decodedSize != length) { + LOG(ERROR) << "decoding bytes len " << s.size() << ", expecting output len " + << length << ", got " << decodedSize; return false; } - if (!B64StandardDecode(data, (byte*) s.data(), s.size())) { + if (!B64StandardDecode(data, (byte *)s.data(), s.size())) { LOG(ERROR) << "B64 decode failure on " << s; return false; } @@ -129,67 +109,51 @@ bool XmlValue::readB64(const char *path, byte *data, int length) const return true; } -bool XmlValue::read(const char *path, Interface *out) const -{ +bool XmlValue::read(const char *path, Interface *out) const { XmlValuePtr node = find(path); - if (!node) - return false; + if (!node) return false; int major, minor; - bool ok = node->read("name", out->mutable_name()) - && node->read("major", &major) - && node->read("minor", &minor); + bool ok = node->read("name", out->mutable_name()) && + node->read("major", &major) && node->read("minor", &minor); - if (!ok) - return false; + if (!ok) return false; out->set_major(major); out->set_minor(minor); return true; } -std::string safeValueForNode(const TiXmlElement *element) -{ +std::string safeValueForNode(const TiXmlElement *element) { std::string value; - if (element == NULL) - return value; + if (element == NULL) return value; const TiXmlNode *child = element->FirstChild(); - if (child) - { + if (child) { const TiXmlText *childText = child->ToText(); - if (childText) - value = childText->Value(); + if (childText) value = childText->Value(); } return value; } -class XmlNode : virtual public XmlValue -{ +class XmlNode : virtual public XmlValue { const TiXmlElement *element; -public: + + public: XmlNode(const TiXmlElement *element_) - : XmlValue(safeValueForNode(element_)) - , element(element_) - { - } + : XmlValue(safeValueForNode(element_)), element(element_) {} - virtual ~XmlNode() - { - } + virtual ~XmlNode() {} - virtual XmlValuePtr find(const char *name) const - { - if (name[0] == '@') - { - const char *value = element->Attribute(name+1); + virtual XmlValuePtr find(const char *name) const { + if (name[0] == '@') { + const char *value = element->Attribute(name + 1); if (value) return XmlValuePtr(new XmlValue(value)); - else + else return XmlValuePtr(); - } else - { + } else { const TiXmlElement *el = element->FirstChildElement(name); if (el) return XmlValuePtr(new XmlNode(el)); @@ -199,39 +163,29 @@ public: } }; -struct XmlReader::XmlReaderData -{ +struct XmlReader::XmlReaderData { shared_ptr doc; }; -XmlReader::XmlReader() - : pd(new XmlReaderData()) -{ -} +XmlReader::XmlReader() : pd(new XmlReaderData()) {} -XmlReader::~XmlReader() -{ -} +XmlReader::~XmlReader() {} -bool XmlReader::load(const char *fileName) -{ +bool XmlReader::load(const char *fileName) { pd->doc.reset(new TiXmlDocument(fileName)); return pd->doc->LoadFile(); } -XmlValuePtr XmlReader::operator[] ( const char *name ) const -{ +XmlValuePtr XmlReader::operator[](const char *name) const { TiXmlNode *node = pd->doc->FirstChild(name); - if (node == NULL) - { + if (node == NULL) { LOG(ERROR) << "Xml node " << name << " not found"; return XmlValuePtr(new XmlValue()); } TiXmlElement *element = node->ToElement(); - if (element == NULL) - { + if (element == NULL) { LOG(ERROR) << "Xml node " << name << " not element, type = " << node->Type(); return XmlValuePtr(new XmlValue()); diff --git a/base/XmlReader.h b/base/XmlReader.h index 37b38b2..18d01f6 100644 --- a/base/XmlReader.h +++ b/base/XmlReader.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + #ifndef _XmlReader_incl_ #define _XmlReader_incl_ @@ -32,26 +32,18 @@ typedef shared_ptr XmlValuePtr; class Interface; -class XmlValue -{ +class XmlValue { std::string value; -public: - XmlValue() - { - } - XmlValue(const std::string &value) - { - this->value = value; - } + public: + XmlValue() {} + + XmlValue(const std::string &value) { this->value = value; } virtual ~XmlValue(); - XmlValuePtr operator[] (const char *path) const; + XmlValuePtr operator[](const char *path) const; - const std::string &text() const - { - return value; - } + const std::string &text() const { return value; } bool read(const char *path, std::string *out) const; bool readB64(const char *path, byte *out, int length) const; @@ -63,13 +55,12 @@ public: bool read(const char *path, Interface *out) const; -protected: + protected: virtual XmlValuePtr find(const char *name) const; }; -class XmlReader -{ -public: +class XmlReader { + public: XmlReader(); ~XmlReader(); @@ -77,7 +68,7 @@ public: XmlValuePtr operator[](const char *name) const; -private: + private: struct XmlReaderData; shared_ptr pd; }; diff --git a/base/autosprintf.cpp b/base/autosprintf.cpp index 842c80a..5b45e1a 100644 --- a/base/autosprintf.cpp +++ b/base/autosprintf.cpp @@ -21,7 +21,7 @@ This must come before because may include , and once has been included, it's too late. */ #ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 +#define _GNU_SOURCE 1 #endif /* Specification. */ @@ -33,46 +33,35 @@ //#include "lib-asprintf.h" #include -namespace gnu -{ +namespace gnu { - /* Constructor: takes a format string and the printf arguments. */ - autosprintf::autosprintf (const char *format, ...) - { - va_list args; - va_start (args, format); - if (vasprintf (&str, format, args) < 0) - str = NULL; - va_end (args); - } - - /* Copy constructor. Necessary because the destructor is nontrivial. */ - autosprintf::autosprintf (const autosprintf& src) - { - str = (src.str != NULL ? strdup (src.str) : NULL); - } - - /* Destructor: frees the temporarily allocated string. */ - autosprintf::~autosprintf () - { - free (str); - } - - /* Conversion to string. */ - autosprintf::operator char * () const - { - if (str != NULL) - { - size_t length = strlen (str) + 1; - char *copy = new char[length]; - memcpy (copy, str, length); - return copy; - } - else - return NULL; - } - autosprintf::operator std::string () const - { - return std::string (str ? str : "(error in autosprintf)"); - } +/* Constructor: takes a format string and the printf arguments. */ +autosprintf::autosprintf(const char *format, ...) { + va_list args; + va_start(args, format); + if (vasprintf(&str, format, args) < 0) str = NULL; + va_end(args); +} + +/* Copy constructor. Necessary because the destructor is nontrivial. */ +autosprintf::autosprintf(const autosprintf &src) { + str = (src.str != NULL ? strdup(src.str) : NULL); +} + +/* Destructor: frees the temporarily allocated string. */ +autosprintf::~autosprintf() { free(str); } + +/* Conversion to string. */ +autosprintf::operator char *() const { + if (str != NULL) { + size_t length = strlen(str) + 1; + char *copy = new char[length]; + memcpy(copy, str, length); + return copy; + } else + return NULL; +} +autosprintf::operator std::string() const { + return std::string(str ? str : "(error in autosprintf)"); +} } diff --git a/base/autosprintf.h b/base/autosprintf.h index ac21ff2..339e60b 100644 --- a/base/autosprintf.h +++ b/base/autosprintf.h @@ -21,46 +21,45 @@ #ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ +#define __attribute__(Spec) /* empty */ +#endif /* The __-protected variants of `format' and `printf' attributes are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +#define __format__ format +#define __printf__ printf +#endif #endif #include #include -namespace gnu -{ - /* A temporary object, usually allocated on the stack, representing - the result of an asprintf() call. */ - class autosprintf - { - public: - /* Constructor: takes a format string and the printf arguments. */ - autosprintf (const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); - /* Copy constructor. */ - autosprintf (const autosprintf& src); - /* Destructor: frees the temporarily allocated string. */ - ~autosprintf (); - /* Conversion to string. */ - operator char * () const; - operator std::string () const; - /* Output to an ostream. */ - friend inline std::ostream& operator<< (std::ostream& stream, const autosprintf& tmp) - { - stream << (tmp.str ? tmp.str : "(error in autosprintf)"); - return stream; - } - private: - char *str; - }; +namespace gnu { +/* A temporary object, usually allocated on the stack, representing + the result of an asprintf() call. */ +class autosprintf { + public: + /* Constructor: takes a format string and the printf arguments. */ + autosprintf(const char* format, ...) + __attribute__((__format__(__printf__, 2, 3))); + /* Copy constructor. */ + autosprintf(const autosprintf& src); + /* Destructor: frees the temporarily allocated string. */ + ~autosprintf(); + /* Conversion to string. */ + operator char*() const; + operator std::string() const; + /* Output to an ostream. */ + friend inline std::ostream& operator<<(std::ostream& stream, + const autosprintf& tmp) { + stream << (tmp.str ? tmp.str : "(error in autosprintf)"); + return stream; + } + + private: + char* str; +}; } #endif /* _AUTOSPRINTF_H */ diff --git a/base/base64.cpp b/base/base64.cpp index 2d22609..071a989 100644 --- a/base/base64.cpp +++ b/base/base64.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -29,33 +29,29 @@ namespace encfs { // arrays. // It is the caller's responsibility to make sure the output array is large // enough. -void changeBase2(byte *src, int srcLen, int src2Pow, - byte *dst, int dstLen, int dst2Pow) -{ - unsigned long work = 0; - int workBits = 0; // number of bits left in the work buffer - byte *end = src + srcLen; - byte *origDst = dst; - const int mask = (1 << dst2Pow) -1; +void changeBase2(byte *src, int srcLen, int src2Pow, byte *dst, int dstLen, + int dst2Pow) { + unsigned long work = 0; + int workBits = 0; // number of bits left in the work buffer + byte *end = src + srcLen; + byte *origDst = dst; + const int mask = (1 << dst2Pow) - 1; - // copy the new bits onto the high bits of the stream. - // The bits that fall off the low end are the output bits. - while(src != end) - { - work |= ((unsigned long)(*src++)) << workBits; - workBits += src2Pow; + // copy the new bits onto the high bits of the stream. + // The bits that fall off the low end are the output bits. + while (src != end) { + work |= ((unsigned long)(*src++)) << workBits; + workBits += src2Pow; - while(workBits >= dst2Pow) - { - *dst++ = work & mask; - work >>= dst2Pow; - workBits -= dst2Pow; - } + while (workBits >= dst2Pow) { + *dst++ = work & mask; + work >>= dst2Pow; + workBits -= dst2Pow; } + } - // now, we could have a partial value left in the work buffer.. - if(workBits && ((dst - origDst) < dstLen)) - *dst++ = work & mask; + // now, we could have a partial value left in the work buffer.. + if (workBits && ((dst - origDst) < dstLen)) *dst++ = work & mask; } /* @@ -65,65 +61,51 @@ void changeBase2(byte *src, int srcLen, int src2Pow, Uses the stack to store output values. Recurse every time a new value is to be written, then write the value at the tail end of the recursion. */ -static -void changeBase2Inline(byte *src, int srcLen, - int src2Pow, int dst2Pow, - bool outputPartialLastByte, - unsigned long work, - int workBits, - byte *outLoc) -{ - const int mask = (1 << dst2Pow) -1; - if(!outLoc) - outLoc = src; +static void changeBase2Inline(byte *src, int srcLen, int src2Pow, int dst2Pow, + bool outputPartialLastByte, unsigned long work, + int workBits, byte *outLoc) { + const int mask = (1 << dst2Pow) - 1; + if (!outLoc) outLoc = src; - // copy the new bits onto the high bits of the stream. - // The bits that fall off the low end are the output bits. - while(srcLen && workBits < dst2Pow) - { - work |= ((unsigned long)(*src++)) << workBits; - workBits += src2Pow; - --srcLen; - } - - // we have at least one value that can be output - byte outVal = work & mask; - work >>= dst2Pow; - workBits -= dst2Pow; - - if(srcLen) - { - // more input left, so recurse - changeBase2Inline( src, srcLen, src2Pow, dst2Pow, - outputPartialLastByte, work, workBits, outLoc+1); - *outLoc = outVal; - } else - { - // no input left, we can write remaining values directly - *outLoc++ = outVal; - - // we could have a partial value left in the work buffer.. - if(outputPartialLastByte) - { - while(workBits > 0) - { - *outLoc++ = work & mask; - work >>= dst2Pow; - workBits -= dst2Pow; - } - } + // copy the new bits onto the high bits of the stream. + // The bits that fall off the low end are the output bits. + while (srcLen && workBits < dst2Pow) { + work |= ((unsigned long)(*src++)) << workBits; + workBits += src2Pow; + --srcLen; + } + + // we have at least one value that can be output + byte outVal = work & mask; + work >>= dst2Pow; + workBits -= dst2Pow; + + if (srcLen) { + // more input left, so recurse + changeBase2Inline(src, srcLen, src2Pow, dst2Pow, outputPartialLastByte, + work, workBits, outLoc + 1); + *outLoc = outVal; + } else { + // no input left, we can write remaining values directly + *outLoc++ = outVal; + + // we could have a partial value left in the work buffer.. + if (outputPartialLastByte) { + while (workBits > 0) { + *outLoc++ = work & mask; + work >>= dst2Pow; + workBits -= dst2Pow; + } } + } } -void changeBase2Inline(byte *src, int srcLen, - int src2Pow, int dst2Pow, - bool outputPartialLastByte) -{ - changeBase2Inline(src, srcLen, src2Pow, dst2Pow, - outputPartialLastByte, 0, 0, 0); +void changeBase2Inline(byte *src, int srcLen, int src2Pow, int dst2Pow, + bool outputPartialLastByte) { + changeBase2Inline(src, srcLen, src2Pow, dst2Pow, outputPartialLastByte, 0, 0, + 0); } - // character set for ascii b64: // ",-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // a standard base64 (eg a64l doesn't use ',-' but uses './'. We don't @@ -131,56 +113,44 @@ void changeBase2Inline(byte *src, int srcLen, // '.' included in the encrypted names, so that it can be reserved for files // with special meaning. static const char B642AsciiTable[] = ",-0123456789"; -void B64ToAscii(byte *in, int length) -{ - for(int offset=0; offset 11) - { - if(ch > 37) + if (ch > 11) { + if (ch > 37) ch += 'a' - 38; else ch += 'A' - 12; } else - ch = B642AsciiTable[ ch ]; + ch = B642AsciiTable[ch]; in[offset] = ch; } } -static const byte Ascii2B64Table[] = - " 01 23456789:; "; - // 0123456789 123456789 123456789 123456789 123456789 123456789 1234 - // 0 1 2 3 4 5 6 -void AsciiToB64(byte *in, int length) -{ - return AsciiToB64(in, in, length); -} +static const byte Ascii2B64Table[] = + " 01 23456789:; "; +// 0123456789 123456789 123456789 123456789 123456789 123456789 1234 +// 0 1 2 3 4 5 6 +void AsciiToB64(byte *in, int length) { return AsciiToB64(in, in, length); } -void AsciiToB64(byte *out, const byte *in, int length) -{ - while(length--) - { +void AsciiToB64(byte *out, const byte *in, int length) { + while (length--) { byte ch = *in++; - if(ch >= 'A') - { - if(ch >= 'a') + if (ch >= 'A') { + if (ch >= 'a') ch += 38 - 'a'; else ch += 12 - 'A'; } else - ch = Ascii2B64Table[ ch ] - '0'; + ch = Ascii2B64Table[ch] - '0'; *out++ = ch; } } - -void B32ToAscii(byte *buf, int len) -{ - for(int offset=0; offset= 0 && ch < 26) ch += 'A'; @@ -191,15 +161,10 @@ void B32ToAscii(byte *buf, int len) } } -void AsciiToB32(byte *in, int length) -{ - return AsciiToB32(in, in, length); -} +void AsciiToB32(byte *in, int length) { return AsciiToB32(in, in, length); } -void AsciiToB32(byte *out, const byte *in, int length) -{ - while(length--) - { +void AsciiToB32(byte *out, const byte *in, int length) { + while (length--) { byte ch = *in++; int lch = toupper(ch); if (lch >= 'A') @@ -211,33 +176,24 @@ void AsciiToB32(byte *out, const byte *in, int length) } } - #define WHITESPACE 64 -#define EQUALS 65 -#define INVALID 66 - +#define EQUALS 65 +#define INVALID 66 + static const byte d[] = { - 66,66,66,66,66,66,66,66,66,64, - 66,66,66,66,66,66,66,66,66,66, - 66,66,66,66,66,66,66,66,66,66, - 66,66,66,66,66,66,66,66,66,66, - 66,66,66,62,66,66,66,63,52,53, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 64, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 62, 66, 66, 66, 63, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 66, 66, // 50-59 + 66, 65, 66, 66, 66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 66, 66, 66, + 66, 66, 66, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 100-109 + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; - 54,55,56,57,58,59,60,61,66,66, // 50-59 - 66,65,66,66,66, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9,10,11,12,13,14, - 15,16,17,18,19,20,21,22,23,24, - 25,66,66,66,66,66,66,26,27,28, - - 29,30,31,32,33,34,35,36,37,38, // 100-109 - 39,40,41,42,43,44,45,46,47,48, - 49,50,51 -}; - -bool B64StandardDecode(byte *out, const byte *in, int inLen) { +bool B64StandardDecode(byte *out, const byte *in, int inLen) { const byte *end = in + inLen; size_t buf = 1; - + while (in < end) { byte v = *in++; if (v > 'z') { @@ -247,31 +203,31 @@ bool B64StandardDecode(byte *out, const byte *in, int inLen) { byte c = d[v]; switch (c) { - case WHITESPACE: continue; /* skip whitespace */ - case INVALID: - LOG(ERROR) << "Invalid character: " << (unsigned int)v; - return false; /* invalid input, return error */ - case EQUALS: /* pad character, end of data */ - in = end; - continue; - default: - buf = buf << 6 | c; - - /* If the buffer is full, split it into bytes */ - if (buf & 0x1000000) { - *out++ = buf >> 16; - *out++ = buf >> 8; - *out++ = buf; - buf = 1; - } + case WHITESPACE: + continue; /* skip whitespace */ + case INVALID: + LOG(ERROR) << "Invalid character: " << (unsigned int)v; + return false; /* invalid input, return error */ + case EQUALS: /* pad character, end of data */ + in = end; + continue; + default: + buf = buf << 6 | c; + + /* If the buffer is full, split it into bytes */ + if (buf & 0x1000000) { + *out++ = buf >> 16; + *out++ = buf >> 8; + *out++ = buf; + buf = 1; + } } } if (buf & 0x40000) { *out++ = buf >> 10; *out++ = buf >> 2; - } - else if (buf & 0x1000) { + } else if (buf & 0x1000) { *out++ = buf >> 4; } diff --git a/base/base64.h b/base/base64.h index 2cfdc65..5977c29 100644 --- a/base/base64.h +++ b/base/base64.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -25,40 +25,33 @@ namespace encfs { -inline int B64ToB256Bytes( int numB64Bytes ) -{ - return (numB64Bytes * 6) / 8; // round down +inline int B64ToB256Bytes(int numB64Bytes) { + return (numB64Bytes * 6) / 8; // round down } -inline int B32ToB256Bytes( int numB32Bytes ) -{ - return (numB32Bytes * 5) / 8; // round down +inline int B32ToB256Bytes(int numB32Bytes) { + return (numB32Bytes * 5) / 8; // round down } -inline int B256ToB64Bytes( int numB256Bytes ) -{ - return (numB256Bytes * 8 + 5) / 6; // round up +inline int B256ToB64Bytes(int numB256Bytes) { + return (numB256Bytes * 8 + 5) / 6; // round up } -inline int B256ToB32Bytes( int numB256Bytes ) -{ - return (numB256Bytes * 8 + 4) / 5; // round up +inline int B256ToB32Bytes(int numB256Bytes) { + return (numB256Bytes * 8 + 4) / 5; // round up } - /* convert data between different bases - each being a power of 2. */ -void changeBase2(byte *src, int srcLength, int srcPow2, - byte *dst, int dstLength, int dstPow2); +void changeBase2(byte *src, int srcLength, int srcPow2, byte *dst, + int dstLength, int dstPow2); /* same as changeBase2, but writes output over the top of input data. */ -void changeBase2Inline(byte *buf, int srcLength, - int srcPow2, int dst2Pow, - bool outputPartialLastByte); - +void changeBase2Inline(byte *buf, int srcLength, int srcPow2, int dst2Pow, + bool outputPartialLastByte); // inplace translation from values [0,2^6] => base64 ASCII void B64ToAscii(byte *buf, int length); @@ -80,4 +73,3 @@ bool B64StandardDecode(byte *out, const byte *in, int inputLen); } // namespace encfs #endif - diff --git a/base/gettext.h b/base/gettext.h index 209921e..6d77d32 100644 --- a/base/gettext.h +++ b/base/gettext.h @@ -23,19 +23,18 @@ #if ENABLE_NLS /* Get declarations of GNU message catalog functions. */ -# include +#include /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by the gettext() and ngettext() macros. This is an alternative to calling textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif +#ifdef DEFAULT_TEXT_DOMAIN +#undef gettext +#define gettext(Msgid) dgettext(DEFAULT_TEXT_DOMAIN, Msgid) +#undef ngettext +#define ngettext(Msgid1, Msgid2, N) \ + dngettext(DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) +#endif #else @@ -46,17 +45,17 @@ and also including would fail on SunOS 4, whereas is OK. */ #if defined(__sun) -# include +#include #endif /* Many header files from the libstdc++ coming with g++ 3.3 or newer include , which chokes if dcgettext is defined as a macro. So include it now, to make later inclusions of a NOP. */ #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif +#include +#if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H +#include +#endif #endif /* Disabled NLS. @@ -64,23 +63,22 @@ for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) +#define gettext(Msgid) ((const char *)(Msgid)) +#define dgettext(Domainname, Msgid) ((void)(Domainname), gettext(Msgid)) +#define dcgettext(Domainname, Msgid, Category) \ + ((void)(Category), dgettext(Domainname, Msgid)) +#define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? ((void)(Msgid2), (const char *)(Msgid1)) \ + : ((void)(Msgid1), (const char *)(Msgid2))) +#define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void)(Domainname), ngettext(Msgid1, Msgid2, N)) +#define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void)(Category), dngettext(Domainname, Msgid1, Msgid2, N)) +#define textdomain(Domainname) ((const char *)(Domainname)) +#define bindtextdomain(Domainname, Dirname) \ + ((void)(Domainname), (const char *)(Dirname)) +#define bind_textdomain_codeset(Domainname, Codeset) \ + ((void)(Domainname), (const char *)(Codeset)) #endif @@ -101,27 +99,33 @@ short and rarely need to change. The letter 'p' stands for 'particular' or 'special'. */ #ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define pgettext(Msgctxt, Msgid) \ + pgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, \ + LC_MESSAGES) #else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define pgettext(Msgctxt, Msgid) \ + pgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define dpgettext(Domainname, Msgctxt, Msgid) \ + pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, \ + LC_MESSAGES) #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) + pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) #ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, \ + Msgid, MsgidPlural, N, LC_MESSAGES) #else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, \ + N, LC_MESSAGES) #endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, \ + MsgidPlural, N, LC_MESSAGES) #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) + npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, \ + MsgidPlural, N, Category) #ifdef __GNUC__ __inline @@ -130,12 +134,10 @@ __inline inline #endif #endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); + static const char * +pgettext_aux(const char *domain, const char *msg_ctxt_id, const char *msgid, + int category) { + const char *translation = dcgettext(domain, msg_ctxt_id, category); if (translation == msg_ctxt_id) return msgid; else @@ -149,14 +151,11 @@ __inline inline #endif #endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ + static const char * +npgettext_aux(const char *domain, const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, int category) { const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + dcngettext(domain, msg_ctxt_id, msgid_plural, n, category); if (translation == msg_ctxt_id || translation == msgid_plural) return (n == 1 ? msgid : msgid_plural); else @@ -169,18 +168,18 @@ npgettext_aux (const char *domain, #include -#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ +#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) + /* || __STDC_VERSION__ >= 199901L */) #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS #include #endif #define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) + dcpgettext_expr(NULL, Msgctxt, Msgid, LC_MESSAGES) #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) + dcpgettext_expr(Domainname, Msgctxt, Msgid, LC_MESSAGES) #ifdef __GNUC__ __inline @@ -189,43 +188,38 @@ __inline inline #endif #endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; + static const char * +dcpgettext_expr(const char *domain, const char *msgctxt, const char *msgid, + int category) { + size_t msgctxt_len = strlen(msgctxt) + 1; + size_t msgid_len = strlen(msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); + char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof(buf) + ? buf + : (char *)malloc(msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); + { + memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcgettext(domain, msg_ctxt_id, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); + if (msg_ctxt_id != buf) free(msg_ctxt_id); #endif - if (translation != msg_ctxt_id) - return translation; - } + if (translation != msg_ctxt_id) return translation; + } return msgid; } #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) + dcnpgettext_expr(NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) + dcnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #ifdef __GNUC__ __inline @@ -234,37 +228,32 @@ __inline inline #endif #endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; + static const char * +dcnpgettext_expr(const char *domain, const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, int category) { + size_t msgctxt_len = strlen(msgctxt) + 1; + size_t msgid_len = strlen(msgid) + 1; const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS char msg_ctxt_id[msgctxt_len + msgid_len]; #else char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); + char *msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof(buf) + ? buf + : (char *)malloc(msgctxt_len + msgid_len)); if (msg_ctxt_id != NULL) #endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + { + memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcngettext(domain, msg_ctxt_id, msgid_plural, n, category); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); + if (msg_ctxt_id != buf) free(msg_ctxt_id); #endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; - } + if (!(translation == msg_ctxt_id || translation == msgid_plural)) + return translation; + } return (n == 1 ? msgid : msgid_plural); } diff --git a/base/i18n.h b/base/i18n.h index 4a73f14..6094a12 100644 --- a/base/i18n.h +++ b/base/i18n.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -23,22 +23,20 @@ #if defined(LOCALEDIR) -# include "base/gettext.h" +#include "base/gettext.h" // make shortcut for gettext -# define _(STR) gettext (STR) +#define _(STR) gettext(STR) -# include "base/autosprintf.h" +#include "base/autosprintf.h" using gnu::autosprintf; #else -# define gettext(STR) (STR) -# define gettext_noop(STR) (STR) -# define _(STR) (STR) -# define N_(STR) (STR) +#define gettext(STR) (STR) +#define gettext_noop(STR) (STR) +#define _(STR) (STR) +#define N_(STR) (STR) #endif #endif - - diff --git a/base/shared_ptr.h b/base/shared_ptr.h index 82b9068..8dda3c9 100644 --- a/base/shared_ptr.h +++ b/base/shared_ptr.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -25,14 +25,13 @@ #include "base/config.h" #ifdef HAVE_TR1_MEMORY - #include - using std::tr1::shared_ptr; - using std::tr1::dynamic_pointer_cast; +#include +using std::tr1::shared_ptr; +using std::tr1::dynamic_pointer_cast; #else - #include - using std::shared_ptr; - using std::dynamic_pointer_cast; +#include +using std::shared_ptr; +using std::dynamic_pointer_cast; #endif #endif - diff --git a/base/types.h b/base/types.h index 2f6d519..b68337f 100644 --- a/base/types.h +++ b/base/types.h @@ -4,7 +4,6 @@ namespace encfs { typedef unsigned char byte; - } -#endif // TYPES_H +#endif // TYPES_H diff --git a/cipher/BlockCipher.cpp b/cipher/BlockCipher.cpp index 8d7e82d..580f00d 100644 --- a/cipher/BlockCipher.cpp +++ b/cipher/BlockCipher.cpp @@ -13,12 +13,10 @@ namespace encfs { -Registry& BlockCipher::GetRegistry() -{ +Registry& BlockCipher::GetRegistry() { static Registry registry; static bool first = true; - if (first) - { + if (first) { #ifdef WITH_OPENSSL OpenSSL::registerCiphers(); #endif @@ -31,13 +29,8 @@ Registry& BlockCipher::GetRegistry() return registry; } -BlockCipher::BlockCipher() -{ -} +BlockCipher::BlockCipher() {} -BlockCipher::~BlockCipher() -{ -} +BlockCipher::~BlockCipher() {} } // namespace encfs - diff --git a/cipher/BlockCipher.h b/cipher/BlockCipher.h index f920a9c..d0970d3 100644 --- a/cipher/BlockCipher.h +++ b/cipher/BlockCipher.h @@ -15,8 +15,7 @@ static const char NAME_BLOWFISH_CBC[] = "Blowfish/CBC"; // BlockCipher is a StreamCipher with a block size. // Encryption and decryption must be in multiples of the block size. -class BlockCipher : public StreamCipher -{ +class BlockCipher : public StreamCipher { public: DECLARE_REGISTERABLE_TYPE(BlockCipher); @@ -25,9 +24,9 @@ class BlockCipher : public StreamCipher // Not valid until a key has been set, as they key size may determine the // block size. - virtual int blockSize() const =0; + virtual int blockSize() const = 0; }; } // namespace encfs -#endif // BLOCKCIPHER_H +#endif // BLOCKCIPHER_H diff --git a/cipher/BlockCipher_test.cpp b/cipher/BlockCipher_test.cpp index 6e09d4c..b5cfdbe 100644 --- a/cipher/BlockCipher_test.cpp +++ b/cipher/BlockCipher_test.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -43,9 +43,7 @@ namespace { class BlockCipherTest : public testing::Test { public: - virtual void SetUp() { - CipherV1::init(false); - } + virtual void SetUp() { CipherV1::init(false); } }; void compare(const byte *a, const byte *b, int size) { @@ -55,10 +53,8 @@ void compare(const byte *a, const byte *b, int size) { #endif for (int i = 0; i < size; i++) { bool match = (a[i] == b[i]); - ASSERT_TRUE(match) << "mismatched data at offset " << i - << " of " << size; - if (!match) - break; + ASSERT_TRUE(match) << "mismatched data at offset " << i << " of " << size; + if (!match) break; } } @@ -79,26 +75,25 @@ TEST_F(BlockCipherTest, RequiredStreamCiphers) { } template -void checkTestVector(const char *cipherName, - const char *hexKey, - const char *hexIv, - const char *hexPlaintext, +void checkTestVector(const char *cipherName, const char *hexKey, + const char *hexIv, const char *hexPlaintext, const char *hexCipher) { SCOPED_TRACE(testing::Message() << "Testing cipher: " << cipherName - << ", key = " << hexKey << ", plaintext = " << hexPlaintext); + << ", key = " << hexKey + << ", plaintext = " << hexPlaintext); auto cipher = T::GetRegistry().CreateForMatch(cipherName); ASSERT_TRUE(cipher != NULL); - CipherKey key(strlen(hexKey)/2); + CipherKey key(strlen(hexKey) / 2); setDataFromHex(key.data(), key.size(), hexKey); ASSERT_TRUE(cipher->setKey(key)); - byte iv[strlen(hexIv)/2]; + byte iv[strlen(hexIv) / 2]; setDataFromHex(iv, sizeof(iv), hexIv); - byte plaintext[strlen(hexPlaintext)/2]; + byte plaintext[strlen(hexPlaintext) / 2]; setDataFromHex(plaintext, sizeof(plaintext), hexPlaintext); byte ciphertext[sizeof(plaintext)]; @@ -120,45 +115,41 @@ void checkTestVector(const char *cipherName, TEST_F(BlockCipherTest, TestVectors) { // BF128 CBC - checkTestVector(NAME_BLOWFISH_CBC, - "0123456789abcdeff0e1d2c3b4a59687", - "fedcba9876543210", + checkTestVector( + NAME_BLOWFISH_CBC, "0123456789abcdeff0e1d2c3b4a59687", "fedcba9876543210", "37363534333231204e6f77206973207468652074696d6520666f722000000000", "6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc"); // BF128 CFB - checkTestVector(NAME_BLOWFISH_CFB, - "0123456789abcdeff0e1d2c3b4a59687", - "fedcba9876543210", + checkTestVector( + NAME_BLOWFISH_CFB, "0123456789abcdeff0e1d2c3b4a59687", "fedcba9876543210", "37363534333231204e6f77206973207468652074696d6520666f722000", "e73214a2822139caf26ecf6d2eb9e76e3da3de04d1517200519d57a6c3"); - + // AES128 CBC - checkTestVector(NAME_AES_CBC, - "2b7e151628aed2a6abf7158809cf4f3c", - "000102030405060708090a0b0c0d0e0f", - "6bc1bee22e409f96e93d7e117393172a", - "7649abac8119b246cee98e9b12e9197d"); - + checkTestVector(NAME_AES_CBC, "2b7e151628aed2a6abf7158809cf4f3c", + "000102030405060708090a0b0c0d0e0f", + "6bc1bee22e409f96e93d7e117393172a", + "7649abac8119b246cee98e9b12e9197d"); + // AES128 CFB - checkTestVector(NAME_AES_CFB, - "2b7e151628aed2a6abf7158809cf4f3c", - "000102030405060708090a0b0c0d0e0f", - "6bc1bee22e409f96e93d7e117393172a", + checkTestVector( + NAME_AES_CFB, "2b7e151628aed2a6abf7158809cf4f3c", + "000102030405060708090a0b0c0d0e0f", "6bc1bee22e409f96e93d7e117393172a", "3b3fd92eb72dad20333449f8e83cfb4a"); // AES256 CBC - checkTestVector(NAME_AES_CBC, + checkTestVector( + NAME_AES_CBC, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", - "000102030405060708090a0b0c0d0e0f", - "6bc1bee22e409f96e93d7e117393172a", + "000102030405060708090a0b0c0d0e0f", "6bc1bee22e409f96e93d7e117393172a", "f58c4c04d6e5f1ba779eabfb5f7bfbd6"); - + // AES256 CFB - checkTestVector(NAME_AES_CFB, + checkTestVector( + NAME_AES_CFB, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", - "000102030405060708090a0b0c0d0e0f", - "6bc1bee22e409f96e93d7e117393172a", + "000102030405060708090a0b0c0d0e0f", "6bc1bee22e409f96e93d7e117393172a", "dc7e84bfda79164b7ecd8486985d3860"); } @@ -168,7 +159,7 @@ TEST_F(BlockCipherTest, BlockEncryptionTest) { shared_ptr pbkdf( PBKDF::GetRegistry().CreateForMatch(NAME_PBKDF2_HMAC_SHA1)); - list ciphers = registry.GetAll(); + list ciphers = registry.GetAll(); for (const string &name : ciphers) { const BlockCipher::Properties *properties = registry.GetProperties(name.c_str()); @@ -179,7 +170,7 @@ TEST_F(BlockCipherTest, BlockEncryptionTest) { keySize += properties->keySize.inc()) { SCOPED_TRACE(testing::Message() << "Key size " << keySize); - shared_ptr cipher (registry.Create(name.c_str())); + shared_ptr cipher(registry.Create(name.c_str())); CipherKey key = pbkdf->randomKey(keySize / 8); ASSERT_TRUE(key.valid()); @@ -206,14 +197,14 @@ TEST_F(BlockCipherTest, BlockEncryptionTest) { MemBlock encrypted; encrypted.allocate(16 * blockSize); - ASSERT_TRUE(cipher->encrypt(iv.data, mb.data, - encrypted.data, 16 * blockSize)); + ASSERT_TRUE( + cipher->encrypt(iv.data, mb.data, encrypted.data, 16 * blockSize)); // Decrypt. MemBlock decrypted; decrypted.allocate(16 * blockSize); - ASSERT_TRUE(cipher->decrypt(iv.data, encrypted.data, - decrypted.data, 16 * blockSize)); + ASSERT_TRUE(cipher->decrypt(iv.data, encrypted.data, decrypted.data, + 16 * blockSize)); compare(mb.data, decrypted.data, 16 * blockSize); } diff --git a/cipher/CipherKey.cpp b/cipher/CipherKey.cpp index 7e45ebb..c2e329f 100644 --- a/cipher/CipherKey.cpp +++ b/cipher/CipherKey.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -27,67 +27,41 @@ namespace encfs { -CipherKey::CipherKey() - : _valid(false) -{ +CipherKey::CipherKey() : _valid(false) {} + +CipherKey::CipherKey(int length) : _valid(true) { + if (length > 0) _mem.reset(new SecureMem(length)); } -CipherKey::CipherKey(int length) - : _valid(true) -{ - if (length > 0) - _mem.reset(new SecureMem(length)); -} - -CipherKey::CipherKey(const byte *data, int length) - : _valid(true) -{ +CipherKey::CipherKey(const byte *data, int length) : _valid(true) { _mem.reset(new SecureMem(length)); memcpy(_mem->data(), data, length); } -CipherKey::CipherKey(const CipherKey& src) - : _valid(src._valid), - _mem(src._mem) -{ -} +CipherKey::CipherKey(const CipherKey &src) + : _valid(src._valid), _mem(src._mem) {} -CipherKey::~CipherKey() -{ -} +CipherKey::~CipherKey() {} -void CipherKey::operator = (const CipherKey& src) -{ +void CipherKey::operator=(const CipherKey &src) { _mem = src._mem; _valid = src._valid; } -byte *CipherKey::data() const -{ - return !_mem ? NULL : _mem->data(); -} +byte *CipherKey::data() const { return !_mem ? NULL : _mem->data(); } -int CipherKey::size() const -{ - return !_mem ? 0 : _mem->size(); -} +int CipherKey::size() const { return !_mem ? 0 : _mem->size(); } -void CipherKey::reset() -{ +void CipherKey::reset() { _mem.reset(); _valid = false; } -bool CipherKey::valid() const -{ - return _valid; -} +bool CipherKey::valid() const { return _valid; } -bool operator == (const CipherKey &a, const CipherKey &b) { - if (a.size() != b.size()) - return false; +bool operator==(const CipherKey &a, const CipherKey &b) { + if (a.size() != b.size()) return false; return memcmp(a.data(), b.data(), a.size()) == 0; } } // namespace encfs - diff --git a/cipher/CipherKey.h b/cipher/CipherKey.h index 4cd6e27..9fc5e9e 100644 --- a/cipher/CipherKey.h +++ b/cipher/CipherKey.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -30,16 +30,15 @@ namespace encfs { class SecureMem; -class CipherKey -{ +class CipherKey { public: CipherKey(); // Creates a key for which valid() returns false. explicit CipherKey(int length); CipherKey(const byte *data, int length); - CipherKey(const CipherKey& src); + CipherKey(const CipherKey &src); ~CipherKey(); - void operator = (const CipherKey& src); + void operator=(const CipherKey &src); byte *data() const; int size() const; @@ -54,9 +53,8 @@ class CipherKey shared_ptr _mem; }; -bool operator == (const CipherKey &a, const CipherKey &b); +bool operator==(const CipherKey &a, const CipherKey &b); } // namespace encfs #endif - diff --git a/cipher/CipherKey_test.cpp b/cipher/CipherKey_test.cpp index 10ee8c7..4c00507 100644 --- a/cipher/CipherKey_test.cpp +++ b/cipher/CipherKey_test.cpp @@ -21,9 +21,7 @@ namespace { class CipherKeyTest : public testing::Test { protected: - virtual void SetUp() { - CipherV1::init(false); - } + virtual void SetUp() { CipherV1::init(false); } }; TEST_F(CipherKeyTest, ReadWrite) { @@ -49,5 +47,4 @@ TEST_F(CipherKeyTest, ReadWrite) { } } - -} // namespace +} // namespace diff --git a/cipher/CipherV1.cpp b/cipher/CipherV1.cpp index cf8478e..82b74f1 100644 --- a/cipher/CipherV1.cpp +++ b/cipher/CipherV1.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -59,15 +59,12 @@ using std::vector; namespace encfs { -const int MAX_KEYLENGTH = 64; // in bytes (256 bit) +const int MAX_KEYLENGTH = 64; // in bytes (256 bit) const int MAX_IVLENGTH = 16; const int KEY_CHECKSUM_BYTES = 4; #ifndef MIN -inline int MIN(int a, int b) -{ - return (a < b) ? a : b; -} +inline int MIN(int a, int b) { return (a < b) ? a : b; } #endif void CipherV1::init(bool threaded) { @@ -91,118 +88,101 @@ void CipherV1::shutdown(bool threaded) { This duplicated some code in OpenSSL, correcting an issue with key lengths produced for Blowfish. */ -bool BytesToKey(const byte *data, int dataLen, - unsigned int rounds, CipherKey *key) -{ +bool BytesToKey(const byte *data, int dataLen, unsigned int rounds, + CipherKey *key) { Registry registry = MAC::GetRegistry(); shared_ptr sha1(registry.CreateForMatch("SHA-1")); - if (!sha1) - return false; + if (!sha1) return false; - if( data == NULL || dataLen == 0 ) - return false; // OpenSSL returns nkey here, but why? It is a failure.. + if (data == NULL || dataLen == 0) + return false; // OpenSSL returns nkey here, but why? It is a failure.. - SecureMem mdBuf( sha1->outputSize() ); + SecureMem mdBuf(sha1->outputSize()); int addmd = 0; int remaining = key->size(); - for(;;) - { + for (;;) { sha1->init(); - if( addmd++ ) - sha1->update(mdBuf.data(), mdBuf.size()); + if (addmd++) sha1->update(mdBuf.data(), mdBuf.size()); sha1->update(data, dataLen); sha1->write(mdBuf.data()); - for(unsigned int i=1; i < rounds; ++i) - { + for (unsigned int i = 1; i < rounds; ++i) { sha1->init(); sha1->update(mdBuf.data(), mdBuf.size()); sha1->write(mdBuf.data()); } int offset = 0; - int toCopy = MIN( remaining, mdBuf.size() - offset ); - if( toCopy ) - { - memcpy( key->data(), mdBuf.data()+offset, toCopy ); + int toCopy = MIN(remaining, mdBuf.size() - offset); + if (toCopy) { + memcpy(key->data(), mdBuf.data() + offset, toCopy); key += toCopy; remaining -= toCopy; offset += toCopy; } - if(remaining == 0) break; + if (remaining == 0) break; } return true; } -long time_diff(const timeval &end, const timeval &start) -{ +long time_diff(const timeval &end, const timeval &start) { return (end.tv_sec - start.tv_sec) * 1000 * 1000 + - (end.tv_usec - start.tv_usec); + (end.tv_usec - start.tv_usec); } -int CipherV1::TimedPBKDF2(const char *pass, int passlen, - const byte *salt, int saltlen, - CipherKey *key, long desiredPDFTime) -{ +int CipherV1::TimedPBKDF2(const char *pass, int passlen, const byte *salt, + int saltlen, CipherKey *key, long desiredPDFTime) { #ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_CHECK_MEM_IS_DEFINED(pass, passlen); VALGRIND_CHECK_MEM_IS_DEFINED(salt, saltlen); #endif Registry registry = PBKDF::GetRegistry(); shared_ptr impl(registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA1)); - if (!impl) - return -1; + if (!impl) return -1; int iter = 1000; timeval start, end; - for(;;) - { - gettimeofday( &start, 0 ); - if (!impl->makeKey(pass, passlen, salt, saltlen, iter, key)) - return -1; + for (;;) { + gettimeofday(&start, 0); + if (!impl->makeKey(pass, passlen, salt, saltlen, iter, key)) return -1; - gettimeofday( &end, 0 ); + gettimeofday(&end, 0); long delta = time_diff(end, start); - if(delta < desiredPDFTime / 8) - { + if (delta < desiredPDFTime / 8) { iter *= 4; - } else if(delta < (5 * desiredPDFTime / 6)) - { + } else if (delta < (5 * desiredPDFTime / 6)) { // estimate number of iterations to get close to desired time - iter = (int)((double)iter * (double)desiredPDFTime - / (double)delta); + iter = (int)((double)iter * (double)desiredPDFTime / (double)delta); } else return iter; } } - // - Version 1:0 used EVP_BytesToKey, which didn't do the right thing for // Blowfish key lengths > 128 bit. -// - Version 2:0 uses BytesToKey. +// - Version 2:0 uses BytesToKey. // 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:2 adds PBKDF2 for password derivation // - Version 3:0 adds a new IV mechanism // - Version 3:1 drops support for verison 1:0 blowfish keys, in order to avoid // having to duplicate the behavior of old EVP_BytesToKey implementations. -static Interface BlowfishInterface = makeInterface( "ssl/blowfish", 3, 1, 1 ); -static Interface AESInterface = makeInterface( "ssl/aes", 3, 1, 2 ); +static Interface BlowfishInterface = makeInterface("ssl/blowfish", 3, 1, 1); +static Interface AESInterface = makeInterface("ssl/aes", 3, 1, 2); -static Interface NullCipherInterface = makeInterface( "nullCipher", 1, 0, 0); +static Interface NullCipherInterface = makeInterface("nullCipher", 1, 0, 0); -static Range BFKeyRange(128,256,32); +static Range BFKeyRange(128, 256, 32); static int BFDefaultKeyLen = 160; -static Range AESKeyRange(128,256,64); +static Range AESKeyRange(128, 256, 64); static int AESDefaultKeyLen = 192; -list CipherV1::GetAlgorithmList() -{ +list CipherV1::GetAlgorithmList() { list result; Registry blockCipherRegistry = BlockCipher::GetRegistry(); @@ -213,7 +193,7 @@ list CipherV1::GetAlgorithmList() alg.iface = AESInterface; alg.keyLength = AESKeyRange; alg.blockSize = Range(64, 4096, 16); - result.push_back(alg); + result.push_back(alg); } if (blockCipherRegistry.GetPropertiesForMatch(NAME_BLOWFISH_CBC) != NULL) { @@ -223,7 +203,7 @@ list CipherV1::GetAlgorithmList() alg.iface = BlowfishInterface; alg.keyLength = BFKeyRange; alg.blockSize = Range(64, 4096, 8); - result.push_back(alg); + result.push_back(alg); } CipherV1::CipherAlgorithm alg; @@ -232,15 +212,14 @@ list CipherV1::GetAlgorithmList() alg.iface = NullCipherInterface; alg.keyLength = Range(0); alg.blockSize = Range(64, 4096, 8); - result.push_back(alg); - + result.push_back(alg); + return result; } -shared_ptr CipherV1::New(const std::string& name, int keyLen) { +shared_ptr CipherV1::New(const std::string &name, int keyLen) { for (auto &it : GetAlgorithmList()) { - if (it.name == name) - return New(it.iface, keyLen); + if (it.name == name) return New(it.iface, keyLen); } return shared_ptr(); @@ -248,18 +227,14 @@ shared_ptr CipherV1::New(const std::string& name, int keyLen) { shared_ptr CipherV1::New(const Interface &iface, int keyLen) { shared_ptr result(new CipherV1()); - if (!result->initCiphers(iface, iface, keyLen)) - result.reset(); + if (!result->initCiphers(iface, iface, keyLen)) result.reset(); return result; } -CipherV1::CipherV1() -{ -} +CipherV1::CipherV1() {} bool CipherV1::initCiphers(const Interface &iface, const Interface &realIface, - int keyLength) -{ + int keyLength) { this->iface = iface; this->realIface = realIface; @@ -270,21 +245,20 @@ bool CipherV1::initCiphers(const Interface &iface, const Interface &realIface, Range keyRange; if (implements(AESInterface, iface)) { - keyRange = AESKeyRange; + keyRange = AESKeyRange; defaultKeyLength = AESDefaultKeyLen; - _blockCipher.reset( blockCipherRegistry.CreateForMatch(NAME_AES_CBC) ); - _streamCipher.reset( streamCipherRegistry.CreateForMatch(NAME_AES_CFB) ); + _blockCipher.reset(blockCipherRegistry.CreateForMatch(NAME_AES_CBC)); + _streamCipher.reset(streamCipherRegistry.CreateForMatch(NAME_AES_CFB)); } else if (implements(BlowfishInterface, iface)) { keyRange = BFKeyRange; defaultKeyLength = BFDefaultKeyLen; - _blockCipher.reset( blockCipherRegistry.CreateForMatch(NAME_BLOWFISH_CBC) ); - _streamCipher.reset( streamCipherRegistry.CreateForMatch - (NAME_BLOWFISH_CFB) ); + _blockCipher.reset(blockCipherRegistry.CreateForMatch(NAME_BLOWFISH_CBC)); + _streamCipher.reset(streamCipherRegistry.CreateForMatch(NAME_BLOWFISH_CFB)); } else if (implements(NullCipherInterface, iface)) { keyRange = Range(0); defaultKeyLength = 0; - _blockCipher.reset( blockCipherRegistry.CreateForMatch("NullCipher") ); - _streamCipher.reset( streamCipherRegistry.CreateForMatch("NullCipher") ); + _blockCipher.reset(blockCipherRegistry.CreateForMatch("NullCipher")); + _streamCipher.reset(streamCipherRegistry.CreateForMatch("NullCipher")); } if (!_blockCipher || !_streamCipher) { @@ -297,8 +271,7 @@ bool CipherV1::initCiphers(const Interface &iface, const Interface &realIface, else _keySize = keyRange.closest(keyLength) / 8; - _pbkdf.reset(PBKDF::GetRegistry().CreateForMatch( - NAME_PBKDF2_HMAC_SHA1)); + _pbkdf.reset(PBKDF::GetRegistry().CreateForMatch(NAME_PBKDF2_HMAC_SHA1)); if (!_pbkdf) { LOG(ERROR) << "PBKDF missing"; return false; @@ -322,14 +295,9 @@ bool CipherV1::initCiphers(const Interface &iface, const Interface &realIface, return true; } -CipherV1::~CipherV1() -{ -} +CipherV1::~CipherV1() {} -Interface CipherV1::interface() const -{ - return realIface; -} +Interface CipherV1::interface() const { return realIface; } /* Create a key from the password. @@ -340,33 +308,27 @@ Interface CipherV1::interface() const */ CipherKey CipherV1::newKey(const char *password, int passwdLength, int *iterationCount, long desiredDuration, - const byte *salt, int saltLen) -{ + const byte *salt, int saltLen) { #ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_CHECK_MEM_IS_DEFINED(password, passwdLength); VALGRIND_CHECK_MEM_IS_DEFINED(salt, saltLen); #endif CipherKey key(_keySize + _ivLength); - if(*iterationCount == 0) - { + if (*iterationCount == 0) { // timed run, fills in iteration count - int res = TimedPBKDF2(password, passwdLength, - salt, saltLen, &key, + int res = TimedPBKDF2(password, passwdLength, salt, saltLen, &key, 1000 * desiredDuration); - if(res <= 0) - { + if (res <= 0) { LOG(ERROR) << "openssl error, PBKDF2 failed"; return CipherKey(); } else { *iterationCount = res; } - } else - { + } else { // known iteration length - if (!_pbkdf->makeKey(password, passwdLength, - salt, saltLen, *iterationCount, &key)) - { + if (!_pbkdf->makeKey(password, passwdLength, salt, saltLen, *iterationCount, + &key)) { LOG(ERROR) << "openssl error, PBKDF2 failed"; return CipherKey(); } @@ -378,8 +340,7 @@ CipherKey CipherV1::newKey(const char *password, int passwdLength, // Deprecated - for use only with filesystems which used a fixed-round PBKDF. // Such configurations are replaced with a new PBKDF2 implementation when the // password is changed or configuration is rewritten. -CipherKey CipherV1::newKey(const char *password, int passwdLength) -{ +CipherKey CipherV1::newKey(const char *password, int passwdLength) { #ifdef HAVE_VALGRIND_MEMCHECK_H VALGRIND_CHECK_MEM_IS_DEFINED(password, passwdLength); #endif @@ -387,37 +348,33 @@ CipherKey CipherV1::newKey(const char *password, int passwdLength) bool ok = BytesToKey((byte *)password, passwdLength, 16, &key); LOG_IF(ERROR, !ok) << "newKey: BytesToKey failed"; - if (!ok) - throw Error("BytesToKey failed"); + if (!ok) throw Error("BytesToKey failed"); return key; } -CipherKey CipherV1::newRandomKey() -{ +CipherKey CipherV1::newRandomKey() { return _pbkdf->randomKey(_keySize + _ivLength); } -bool CipherV1::pseudoRandomize( byte *buf, int len ) -{ +bool CipherV1::pseudoRandomize(byte *buf, int len) { return _pbkdf->pseudoRandom(buf, len); } bool CipherV1::setKey(const CipherKey &keyIv) { Lock l(_hmacMutex); - LOG_IF(ERROR, (int)(_keySize + _ivLength) != keyIv.size()) - << "Mismatched key size: passed " - << keyIv.size() << ", expecting " << _keySize; + LOG_IF(ERROR, (int)(_keySize + _ivLength) != keyIv.size()) + << "Mismatched key size: passed " << keyIv.size() << ", expecting " + << _keySize; // Key is actually key plus iv, so extract the different parts. CipherKey key(_keySize); memcpy(key.data(), keyIv.data(), _keySize); memcpy(_iv->data(), keyIv.data() + _keySize, _ivLength); - if (_blockCipher->setKey(key) - && _streamCipher->setKey(key) - && _hmac->setKey(key)) { + if (_blockCipher->setKey(key) && _streamCipher->setKey(key) && + _hmac->setKey(key)) { _keySet = true; return true; } @@ -426,24 +383,21 @@ bool CipherV1::setKey(const CipherKey &keyIv) { } uint64_t CipherV1::MAC_64(const byte *data, int len, - uint64_t *chainedIV ) const -{ - rAssert( len > 0 ); - rAssert( _keySet ); + uint64_t *chainedIV) const { + rAssert(len > 0); + rAssert(_keySet); byte md[_hmac->outputSize()]; - + Lock l(_hmacMutex); _hmac->init(); _hmac->update(data, len); - if(chainedIV) - { + if (chainedIV) { // toss in the chained IV as well uint64_t tmp = *chainedIV; byte h[8]; - for(unsigned int i=0; i<8; ++i) - { + for (unsigned int i = 0; i < 8; ++i) { h[i] = tmp & 0xff; tmp >>= 8; } @@ -455,174 +409,151 @@ uint64_t CipherV1::MAC_64(const byte *data, int len, rAssert(ok); // chop this down to a 64bit value.. - byte h[8] = {0,0,0,0,0,0,0,0}; + byte h[8] = {0, 0, 0, 0, 0, 0, 0, 0}; // XXX: the last byte off the hmac isn't used. This minor inconsistency // must be maintained in order to maintain backward compatiblity with earlier // releases. - for(int i=0; i<_hmac->outputSize()-1; ++i) - h[i%8] ^= (byte)(md[i]); + for (int i = 0; i < _hmac->outputSize() - 1; ++i) h[i % 8] ^= (byte)(md[i]); uint64_t value = (uint64_t)h[0]; - for(int i=1; i<8; ++i) - value = (value << 8) | (uint64_t)h[i]; + for (int i = 1; i < 8; ++i) value = (value << 8) | (uint64_t)h[i]; // TODO: should not be here. - if(chainedIV) - *chainedIV = value; + if (chainedIV) *chainedIV = value; return value; } -unsigned int CipherV1::reduceMac32(uint64_t mac64) -{ +unsigned int CipherV1::reduceMac32(uint64_t mac64) { return ((mac64 >> 32) & 0xffffffff) ^ (mac64 & 0xffffffff); } -unsigned int CipherV1::reduceMac16(uint64_t mac64) -{ +unsigned int CipherV1::reduceMac16(uint64_t mac64) { unsigned int mac32 = reduceMac32(mac64); return ((mac32 >> 16) & 0xffff) ^ (mac32 & 0xffff); } -CipherKey CipherV1::readKey(const byte *data, bool checkKey) -{ - rAssert( _keySet ); +CipherKey CipherV1::readKey(const byte *data, bool checkKey) { + rAssert(_keySet); CipherKey key(_keySize + _ivLength); // First N bytes are checksum bytes. unsigned int checksum = 0; - for(int i=0; i>= 8; } - memcpy( out+KEY_CHECKSUM_BYTES, tmpBuf.data(), tmpBuf.size() ); + memcpy(out + KEY_CHECKSUM_BYTES, tmpBuf.data(), tmpBuf.size()); } -std::string CipherV1::encodeAsString(const CipherKey &key) -{ - rAssert( _keySet ); +std::string CipherV1::encodeAsString(const CipherKey &key) { + rAssert(_keySet); int encodedSize = encodedKeySize(); vector buf(encodedSize); writeKey(key, buf.data()); - int b64Len = B256ToB64Bytes( encodedSize ); + int b64Len = B256ToB64Bytes(encodedSize); byte *b64Key = new byte[b64Len + 1]; - changeBase2( buf.data(), encodedSize, 8, b64Key, b64Len, 6); - B64ToAscii( b64Key, b64Len ); - b64Key[ b64Len - 1 ] = '\0'; + changeBase2(buf.data(), encodedSize, 8, b64Key, b64Len, 6); + B64ToAscii(b64Key, b64Len); + b64Key[b64Len - 1] = '\0'; - return string( (const char *)b64Key ); + return string((const char *)b64Key); } -int CipherV1::encodedKeySize() const -{ +int CipherV1::encodedKeySize() const { return _keySize + _ivLength + KEY_CHECKSUM_BYTES; } -int CipherV1::keySize() const -{ - return _keySize; -} +int CipherV1::keySize() const { return _keySize; } -int CipherV1::cipherBlockSize() const -{ - return _blockCipher->blockSize(); -} +int CipherV1::cipherBlockSize() const { return _blockCipher->blockSize(); } // Deprecated: For backward compatibility only. // A watermark attack was published against this data-independent IV schedule. // The replacement incorporates the filesystem key, making it unique to each // filesystem. -static void setIVec_old(byte *ivec, int ivLen, unsigned int seed) -{ - unsigned int var1 = 0x060a4011 * seed; +static void setIVec_old(byte *ivec, int ivLen, unsigned int seed) { + unsigned int var1 = 0x060a4011 * seed; unsigned int var2 = 0x0221040d * (seed ^ 0xD3FEA11C); ivec[0] ^= (var1 >> 24) & 0xff; ivec[1] ^= (var2 >> 16) & 0xff; - ivec[2] ^= (var1 >> 8 ) & 0xff; - ivec[3] ^= (var2 ) & 0xff; + ivec[2] ^= (var1 >> 8) & 0xff; + ivec[3] ^= (var2) & 0xff; ivec[4] ^= (var2 >> 24) & 0xff; ivec[5] ^= (var1 >> 16) & 0xff; - ivec[6] ^= (var2 >> 8 ) & 0xff; - ivec[7] ^= (var1 ) & 0xff; + ivec[6] ^= (var2 >> 8) & 0xff; + ivec[7] ^= (var1) & 0xff; - if(ivLen > 8) - { - ivec[8+0] ^= (var1 ) & 0xff; - ivec[8+1] ^= (var2 >> 8 ) & 0xff; - ivec[8+2] ^= (var1 >> 16) & 0xff; - ivec[8+3] ^= (var2 >> 24) & 0xff; - ivec[8+4] ^= (var1 >> 24) & 0xff; - ivec[8+5] ^= (var2 >> 16) & 0xff; - ivec[8+6] ^= (var1 >> 8 ) & 0xff; - ivec[8+7] ^= (var2 ) & 0xff; + if (ivLen > 8) { + ivec[8 + 0] ^= (var1) & 0xff; + ivec[8 + 1] ^= (var2 >> 8) & 0xff; + ivec[8 + 2] ^= (var1 >> 16) & 0xff; + ivec[8 + 3] ^= (var2 >> 24) & 0xff; + ivec[8 + 4] ^= (var1 >> 24) & 0xff; + ivec[8 + 5] ^= (var2 >> 16) & 0xff; + ivec[8 + 6] ^= (var1 >> 8) & 0xff; + ivec[8 + 7] ^= (var2) & 0xff; } } -void CipherV1::setIVec(byte *ivec, uint64_t seed) const -{ - rAssert( _keySet ); - memcpy( ivec, _iv->data(), _ivLength ); - if (iface.major() < 3) - { +void CipherV1::setIVec(byte *ivec, uint64_t seed) const { + rAssert(_keySet); + memcpy(ivec, _iv->data(), _ivLength); + if (iface.major() < 3) { // Backward compatible mode. setIVec_old(ivec, _ivLength, seed); return; } vector md(_hmac->outputSize()); - for(int i=0; i<8; ++i) - { + for (int i = 0; i < 8; ++i) { md[i] = (byte)(seed & 0xff); seed >>= 8; } @@ -637,102 +568,86 @@ void CipherV1::setIVec(byte *ivec, uint64_t seed) const memcpy(ivec, md.data(), _ivLength); } -static void flipBytes(byte *buf, int size) -{ +static void flipBytes(byte *buf, int size) { byte revBuf[64]; int bytesLeft = size; - while(bytesLeft) - { - int toFlip = MIN( (int)sizeof(revBuf), bytesLeft ); + while (bytesLeft) { + int toFlip = MIN((int)sizeof(revBuf), bytesLeft); - for(int i=0; i 0 ); +bool CipherV1::streamEncode(byte *buf, int size, uint64_t iv64) const { + rAssert(_keySet); + rAssert(size > 0); vector ivec(_ivLength); - shuffleBytes( buf, size ); + shuffleBytes(buf, size); - setIVec( ivec.data(), iv64 ); - if (!_streamCipher->encrypt(ivec.data(), buf, buf, size)) - return false; + setIVec(ivec.data(), iv64); + if (!_streamCipher->encrypt(ivec.data(), buf, buf, size)) return false; - flipBytes( buf, size ); - shuffleBytes( buf, size ); + flipBytes(buf, size); + shuffleBytes(buf, size); - setIVec( ivec.data(), iv64 + 1 ); - if (!_streamCipher->encrypt(ivec.data(), buf, buf, size)) - return false; + setIVec(ivec.data(), iv64 + 1); + if (!_streamCipher->encrypt(ivec.data(), buf, buf, size)) return false; return true; } -bool CipherV1::streamDecode(byte *buf, int size, uint64_t iv64) const -{ - rAssert( _keySet ); - rAssert( size > 0 ); +bool CipherV1::streamDecode(byte *buf, int size, uint64_t iv64) const { + rAssert(_keySet); + rAssert(size > 0); vector ivec(_ivLength); - setIVec( ivec.data(), iv64 + 1 ); - if (!_streamCipher->decrypt(ivec.data(), buf, buf, size)) - return false; + setIVec(ivec.data(), iv64 + 1); + if (!_streamCipher->decrypt(ivec.data(), buf, buf, size)) return false; - unshuffleBytes( buf, size ); - flipBytes( buf, size ); + unshuffleBytes(buf, size); + flipBytes(buf, size); - setIVec( ivec.data(), iv64 ); - if (!_streamCipher->decrypt(ivec.data(), buf, buf, size)) - return false; + setIVec(ivec.data(), iv64); + if (!_streamCipher->decrypt(ivec.data(), buf, buf, size)) return false; - unshuffleBytes( buf, size ); + unshuffleBytes(buf, size); return true; } - -bool CipherV1::blockEncode(byte *buf, int size, uint64_t iv64) const -{ - rAssert( _keySet ); - rAssert( size > 0 ); +bool CipherV1::blockEncode(byte *buf, int size, uint64_t iv64) const { + rAssert(_keySet); + rAssert(size > 0); vector ivec(_ivLength); - setIVec( ivec.data(), iv64 ); + setIVec(ivec.data(), iv64); return _blockCipher->encrypt(ivec.data(), buf, buf, size); } -bool CipherV1::blockDecode(byte *buf, int size, uint64_t iv64) const -{ - rAssert( _keySet ); - rAssert( size > 0 ); +bool CipherV1::blockDecode(byte *buf, int size, uint64_t iv64) const { + rAssert(_keySet); + rAssert(size > 0); vector ivec(_ivLength); - setIVec( ivec.data(), iv64 ); + setIVec(ivec.data(), iv64); return _blockCipher->decrypt(ivec.data(), buf, buf, size); } diff --git a/cipher/CipherV1.h b/cipher/CipherV1.h index 03a840a..3a197d4 100644 --- a/cipher/CipherV1.h +++ b/cipher/CipherV1.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -72,8 +72,7 @@ class SecureMem; initial value vector to randomize the output. But it makes the code simpler to reuse the encryption algorithm as is. */ -class CipherV1 -{ +class CipherV1 { Interface iface; Interface realIface; @@ -85,16 +84,14 @@ class CipherV1 mutable Mutex _hmacMutex; mutable shared_ptr _hmac; - unsigned int _keySize; // in bytes + unsigned int _keySize; // in bytes unsigned int _ivLength; shared_ptr _iv; bool _keySet; public: - - struct CipherAlgorithm - { + struct CipherAlgorithm { std::string name; std::string description; Interface iface; @@ -113,23 +110,22 @@ class CipherV1 // Password-based key derivation function which determines the // number of iterations based on a desired execution time (in microseconds). // Returns the number of iterations applied. - static int TimedPBKDF2(const char *pass, int passLen, - const byte *salt, int saltLen, - CipherKey *out, long desiredPDFTimeMicroseconds); + static int TimedPBKDF2(const char *pass, int passLen, const byte *salt, + int saltLen, CipherKey *out, + long desiredPDFTimeMicroseconds); CipherV1(); ~CipherV1(); - bool initCiphers(const Interface &iface, - const Interface &realIface, int keyLength); + bool initCiphers(const Interface &iface, const Interface &realIface, + int keyLength); // returns the real interface, not the one we're emulating (if any).. Interface interface() const; // create a new key based on a password - CipherKey newKey(const char *password, int passwdLength, - int *iterationCount, long desiredDuration, - const byte *salt, int saltLen); + CipherKey newKey(const char *password, int passwdLength, int *iterationCount, + long desiredDuration, const byte *salt, int saltLen); // deprecated - for backward compatibility CipherKey newKey(const char *password, int passwdLength); // create a new random key @@ -140,11 +136,10 @@ class CipherV1 CipherKey readKey(const byte *data, bool checkKey); // Encrypt and write the given key. - void writeKey(const CipherKey &key, byte *data); + void writeKey(const CipherKey &key, byte *data); // Encrypt and store a key as a string. std::string encodeAsString(const CipherKey &key); - // meta-data about the cypher int keySize() const; @@ -156,8 +151,7 @@ class CipherV1 // Sets the key used for encoding / decoding, and MAC operations. bool setKey(const CipherKey &key); - uint64_t MAC_64(const byte *src, int len, - uint64_t *augment = NULL) const; + uint64_t MAC_64(const byte *src, int len, uint64_t *augment = NULL) const; static unsigned int reduceMac32(uint64_t mac64); static unsigned int reduceMac16(uint64_t mac64); @@ -184,4 +178,3 @@ class CipherV1 } // namespace encfs #endif - diff --git a/cipher/CommonCrypto.cpp b/cipher/CommonCrypto.cpp index 0e405a1..e91efb8 100644 --- a/cipher/CommonCrypto.cpp +++ b/cipher/CommonCrypto.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -42,18 +42,16 @@ namespace commoncrypto { class PbkdfPkcs5Hmac : public PBKDF { CCPseudoRandomAlgorithm prf_; -public: - PbkdfPkcs5Hmac(CCPseudoRandomAlgorithm prf) - : prf_(prf) {} + + public: + PbkdfPkcs5Hmac(CCPseudoRandomAlgorithm prf) : prf_(prf) {} virtual ~PbkdfPkcs5Hmac() {} - + virtual bool makeKey(const char *password, int passwordLength, - const byte *salt, int saltLength, - int numIterations, + const byte *salt, int saltLength, int numIterations, CipherKey *outKey) { - int ret = CCKeyDerivationPBKDF(kCCPBKDF2, password, passwordLength, - salt, saltLength, prf_, - numIterations, + int ret = CCKeyDerivationPBKDF(kCCPBKDF2, password, passwordLength, salt, + saltLength, prf_, numIterations, outKey->data(), outKey->size()); if (ret != 0) { PLOG(ERROR) << "CCKeyDerivationPBKDF failed"; @@ -75,7 +73,7 @@ public: #endif return key; } - + virtual bool pseudoRandom(byte *out, int length) { if (length == 0) return true; #ifdef HAVE_SEC_RANDOM_H @@ -90,9 +88,8 @@ public: } }; - class PbkdfPkcs5HmacSha1CC : public PbkdfPkcs5Hmac { -public: + public: PbkdfPkcs5HmacSha1CC() : PbkdfPkcs5Hmac(kCCPRFHmacAlgSHA1) {} ~PbkdfPkcs5HmacSha1CC() {} @@ -106,7 +103,7 @@ public: REGISTER_CLASS(PbkdfPkcs5HmacSha1CC, PBKDF); class PbkdfPkcs5HmacSha256CC : public PbkdfPkcs5Hmac { -public: + public: PbkdfPkcs5HmacSha256CC() : PbkdfPkcs5Hmac(kCCPRFHmacAlgSHA256) {} ~PbkdfPkcs5HmacSha256CC() {} @@ -123,9 +120,10 @@ class CCCipher : public BlockCipher { CipherKey key; CCAlgorithm algorithm; CCMode mode; + public: - CCCipher() { } - virtual ~CCCipher() { } + CCCipher() {} + virtual ~CCCipher() {} bool rekey(const CipherKey &key, CCAlgorithm algorithm, CCMode mode) { this->key = key; @@ -136,20 +134,18 @@ class CCCipher : public BlockCipher { virtual bool encrypt(const byte *iv, const byte *in, byte *out, int size) { CCCryptorRef cryptor; - CCCryptorCreateWithMode(kCCEncrypt, mode, algorithm, 0, - iv, key.data(), key.size(), - NULL, 0, 0, 0, &cryptor); + CCCryptorCreateWithMode(kCCEncrypt, mode, algorithm, 0, iv, key.data(), + key.size(), NULL, 0, 0, 0, &cryptor); size_t updateLength = 0; CCCryptorUpdate(cryptor, in, size, out, size, &updateLength); CCCryptorRelease(cryptor); return true; } - + virtual bool decrypt(const byte *iv, const byte *in, byte *out, int size) { CCCryptorRef cryptor; - CCCryptorCreateWithMode(kCCDecrypt, mode, algorithm, 0, - iv, key.data(), key.size(), - NULL, 0, 0, 0, &cryptor); + CCCryptorCreateWithMode(kCCDecrypt, mode, algorithm, 0, iv, key.data(), + key.size(), NULL, 0, 0, 0, &cryptor); size_t updateLength = 0; CCCryptorUpdate(cryptor, in, size, out, size, &updateLength); CCCryptorRelease(cryptor); @@ -166,12 +162,10 @@ class BfCbc : public CCCipher { return CCCipher::rekey(key, kCCAlgorithmBlowfish, kCCModeCBC); } - virtual int blockSize() const { - return kCCBlockSizeBlowfish; - } + virtual int blockSize() const { return kCCBlockSizeBlowfish; } static Properties GetProperties() { - return Properties(Range(128,256,32), "Blowfish", "CBC", "CommonCrypto"); + return Properties(Range(128, 256, 32), "Blowfish", "CBC", "CommonCrypto"); } }; REGISTER_CLASS(BfCbc, BlockCipher); @@ -184,13 +178,11 @@ class AesCbc : public CCCipher { virtual bool setKey(const CipherKey &key) { return CCCipher::rekey(key, kCCAlgorithmAES128, kCCModeCBC); } - - virtual int blockSize() const { - return kCCBlockSizeAES128; - } - + + virtual int blockSize() const { return kCCBlockSizeAES128; } + static Properties GetProperties() { - return Properties(Range(128,256,64), "AES", "CBC", "CommonCrypto"); + return Properties(Range(128, 256, 64), "AES", "CBC", "CommonCrypto"); } }; REGISTER_CLASS(AesCbc, BlockCipher); @@ -207,7 +199,7 @@ class BfCfb : public CCCipher { virtual int blockSize() const { return 1; } static Properties GetProperties() { - return Properties(Range(128,256,32), "Blowfish", "CFB", "CommonCrypto"); + return Properties(Range(128, 256, 32), "Blowfish", "CFB", "CommonCrypto"); } }; REGISTER_CLASS(BfCfb, StreamCipher); @@ -220,11 +212,11 @@ class AesCfb : public CCCipher { virtual bool setKey(const CipherKey &key) { return CCCipher::rekey(key, kCCAlgorithmAES128, kCCModeCFB); } - + virtual int blockSize() const { return 1; } static Properties GetProperties() { - return Properties(Range(128,256,64), "AES", "CFB", "CommonCrypto"); + return Properties(Range(128, 256, 64), "AES", "CFB", "CommonCrypto"); } }; REGISTER_CLASS(AesCfb, StreamCipher); @@ -234,9 +226,7 @@ class Sha1HMac : public MAC { Sha1HMac() {} virtual ~Sha1HMac() {} - virtual int outputSize() const { - return CC_SHA1_DIGEST_LENGTH; - } + virtual int outputSize() const { return CC_SHA1_DIGEST_LENGTH; } virtual bool setKey(const CipherKey &key) { this->key = key; @@ -253,7 +243,7 @@ class Sha1HMac : public MAC { } } - virtual bool update (const byte *in, int length) { + virtual bool update(const byte *in, int length) { CCHmacUpdate(&ctx, in, length); return true; } @@ -280,7 +270,6 @@ REGISTER_CLASS(Sha1HMac, MAC); } // namespace commoncrypto -void CommonCrypto::registerCiphers() { -} +void CommonCrypto::registerCiphers() {} } // namespace encfs diff --git a/cipher/CommonCrypto.h b/cipher/CommonCrypto.h index d08289b..ae2bce6 100644 --- a/cipher/CommonCrypto.h +++ b/cipher/CommonCrypto.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -30,6 +30,4 @@ struct CommonCrypto { } // namespace encfs - #endif - diff --git a/cipher/MAC.cpp b/cipher/MAC.cpp index 8534d77..4772f7c 100644 --- a/cipher/MAC.cpp +++ b/cipher/MAC.cpp @@ -4,13 +4,8 @@ namespace encfs { DEFINE_REGISTERABLE_TYPE(MAC) -MAC::MAC() -{ -} +MAC::MAC() {} -MAC::~MAC() -{ -} +MAC::~MAC() {} } // namespace encfs - diff --git a/cipher/MAC.h b/cipher/MAC.h index d0b7fd5..d73349c 100644 --- a/cipher/MAC.h +++ b/cipher/MAC.h @@ -12,35 +12,32 @@ namespace encfs { static const char NAME_SHA1_HMAC[] = "SHA-1/HMAC"; // MAC provides keyed MessageAuthenticationCode algorithms, eg HMAC. -class MAC -{ +class MAC { public: DECLARE_REGISTERABLE_TYPE(MAC); struct Properties { - int blockSize; // Block length of hash function. + int blockSize; // Block length of hash function. std::string hashFunction; std::string mode; std::string library; - std::string toString() const { - return hashFunction + "/" + mode; - } + std::string toString() const { return hashFunction + "/" + mode; } }; MAC(); virtual ~MAC(); - virtual int outputSize() const =0; + virtual int outputSize() const = 0; - virtual bool setKey(const CipherKey &key) =0; + virtual bool setKey(const CipherKey &key) = 0; // Init must be called before any calls to update. - virtual void init() =0; - virtual bool update(const byte *in, int length) =0; - virtual bool write(byte *out) =0; + virtual void init() = 0; + virtual bool update(const byte *in, int length) = 0; + virtual bool write(byte *out) = 0; }; } // namespace encfs -#endif // ENCFS_MAC_H +#endif // ENCFS_MAC_H diff --git a/cipher/MAC_test.cpp b/cipher/MAC_test.cpp index 7afc7d9..07f7715 100644 --- a/cipher/MAC_test.cpp +++ b/cipher/MAC_test.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -19,7 +19,6 @@ * along with this program. If not, see . */ - #include #include @@ -34,15 +33,14 @@ namespace { TEST(HMacSha1Test, MAC) { Registry registry = MAC::GetRegistry(); - shared_ptr hmac( registry.CreateForMatch( NAME_SHA1_HMAC )); + shared_ptr hmac(registry.CreateForMatch(NAME_SHA1_HMAC)); ASSERT_FALSE(!hmac); // Test cases from rfc2202 // Test case 1 CipherKey key(20); byte out[20]; - for (int i = 0; i < 20; ++i) - key.data()[i] = 0x0b; + for (int i = 0; i < 20; ++i) key.data()[i] = 0x0b; hmac->setKey(key); hmac->init(); hmac->update((byte *)"Hi There", 8); @@ -59,8 +57,7 @@ TEST(HMacSha1Test, MAC) { // Test case 3 key = CipherKey(20); - for (int i = 0; i < 20; ++i) - key.data()[i] = 0xaa; + for (int i = 0; i < 20; ++i) key.data()[i] = 0xaa; hmac->setKey(key); hmac->init(); { @@ -82,6 +79,4 @@ TEST(HMacSha1Test, MAC) { ASSERT_EQ("e8e99d0f45237d786d6bbaa7965c7808bbff1a91", stringToHex(out, 20)); } - } // namespace - diff --git a/cipher/MemoryPool.cpp b/cipher/MemoryPool.cpp index 0b5e14d..ba2c63e 100644 --- a/cipher/MemoryPool.cpp +++ b/cipher/MemoryPool.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -35,34 +35,32 @@ #ifdef HAVE_VALGRIND_MEMCHECK_H #include #else -#define VALGRIND_MAKE_MEM_NOACCESS( a, b ) -#define VALGRIND_MAKE_MEM_UNDEFINED( a, b ) +#define VALGRIND_MAKE_MEM_NOACCESS(a, b) +#define VALGRIND_MAKE_MEM_UNDEFINED(a, b) #endif #include #include #ifdef WITH_OPENSSL -# include -# include +#include +#include #endif #ifdef WITH_BOTAN -# include -# include +#include +#include #endif namespace encfs { #ifdef WITH_OPENSSL -static byte *allocBlock( int size ) -{ +static byte *allocBlock(int size) { byte *block = (byte *)OPENSSL_malloc(size); return block; } -static void freeBlock( byte *block, int size ) -{ +static void freeBlock(byte *block, int size) { OPENSSL_cleanse(block, size); OPENSSL_free(block); } @@ -78,88 +76,69 @@ unsigned char cleanse_ctr = 0; static void freeBlock(byte *data, int len) { byte *p = data; size_t loop = len, ctr = cleanse_ctr; - while(loop--) - { + while (loop--) { *(p++) = (unsigned char)ctr; ctr += (17 + ((size_t)p & 0xF)); } // Try to ensure the compiler doesn't optimize away the loop. - p=(byte *)memchr(data, (unsigned char)ctr, len); - if(p) - ctr += (63 + (size_t)p); + p = (byte *)memchr(data, (unsigned char)ctr, len); + if (p) ctr += (63 + (size_t)p); cleanse_ctr = (unsigned char)ctr; delete[] data; } #endif -void MemBlock::allocate(int size) -{ +void MemBlock::allocate(int size) { rAssert(size > 0); this->data = allocBlock(size); this->size = size; } -MemBlock::~MemBlock() -{ - freeBlock(data, size); -} +MemBlock::~MemBlock() { freeBlock(data, size); } #ifdef WITH_BOTAN -SecureMem::SecureMem(int len) - : data_(new Botan::SecureVector(len)) -{ +SecureMem::SecureMem(int len) + : data_(new Botan::SecureVector(len)) { rAssert(len > 0); } -SecureMem::~SecureMem() -{ -# if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) +SecureMem::~SecureMem() { +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1, 11, 0) data_->destroy(); -# endif +#endif delete data_; } -byte* SecureMem::data() const { - return const_cast(data_->begin()); -} +byte *SecureMem::data() const { return const_cast(data_->begin()); } -int SecureMem::size() const { - return data_->size(); -} +int SecureMem::size() const { return data_->size(); } #else -SecureMem::SecureMem(int len) -{ +SecureMem::SecureMem(int len) { rAssert(len > 0); data_ = allocBlock(len); - if (data_) - { + if (data_) { size_ = len; mlock(data_, size_); - } else - { + } else { size_ = 0; } -} +} -SecureMem::~SecureMem() -{ - if (size_) - { +SecureMem::~SecureMem() { + if (size_) { freeBlock(data_, size_); munlock(data_, size_); data_ = NULL; size_ = 0; } -} +} #endif -bool operator == (const SecureMem &a, const SecureMem &b) { - return (a.size() == b.size()) && - (memcmp(a.data(), b.data(), a.size()) == 0); +bool operator==(const SecureMem &a, const SecureMem &b) { + return (a.size() == b.size()) && (memcmp(a.data(), b.data(), a.size()) == 0); } } // namespace encfs - diff --git a/cipher/MemoryPool.h b/cipher/MemoryPool.h index 8429545..c7a5db7 100644 --- a/cipher/MemoryPool.h +++ b/cipher/MemoryPool.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -26,7 +26,8 @@ #ifdef WITH_BOTAN namespace Botan { -template class SecureVector; +template +class SecureVector; } #endif @@ -44,26 +45,21 @@ namespace encfs { // memblock freed when destructed */ -struct MemBlock -{ - byte *data; - int size; +struct MemBlock { + byte *data; + int size; - MemBlock(); - ~MemBlock(); + MemBlock(); + ~MemBlock(); - void allocate(int size); + void allocate(int size); }; -inline MemBlock::MemBlock() - : data(0), size(0) -{ -} +inline MemBlock::MemBlock() : data(0), size(0) {} -class SecureMem -{ +class SecureMem { public: - byte* data() const; + byte *data() const; int size() const; explicit SecureMem(int len); @@ -79,17 +75,12 @@ class SecureMem }; #ifndef WITH_BOTAN -inline byte* SecureMem::data() const { - return data_; -} -inline int SecureMem::size() const { - return size_; -} +inline byte *SecureMem::data() const { return data_; } +inline int SecureMem::size() const { return size_; } #endif -bool operator == (const SecureMem &a, const SecureMem &b); +bool operator==(const SecureMem &a, const SecureMem &b); } // namespace encfs #endif - diff --git a/cipher/NullCiphers.cpp b/cipher/NullCiphers.cpp index b09ed4c..503365b 100644 --- a/cipher/NullCiphers.cpp +++ b/cipher/NullCiphers.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -30,25 +30,19 @@ class NullCipher : public BlockCipher { public: virtual ~NullCipher() {} - virtual int blockSize() const { - return 8; - } + virtual int blockSize() const { return 8; } - virtual bool setKey(const CipherKey &key) { + virtual bool setKey(const CipherKey &key) { return true; } + + virtual bool encrypt(const byte *iv, const byte *in, byte *out, + int numBytes) { + if (in != out) memcpy(out, in, numBytes); return true; } - virtual bool encrypt(const byte *iv, const byte *in, - byte *out, int numBytes) { - if (in != out) - memcpy(out, in, numBytes); - return true; - } - - virtual bool decrypt(const byte *iv, const byte *in, - byte *out, int numBytes) { - if (in != out) - memcpy(out, in, numBytes); + virtual bool decrypt(const byte *iv, const byte *in, byte *out, + int numBytes) { + if (in != out) memcpy(out, in, numBytes); return true; } @@ -66,8 +60,7 @@ REGISTER_CLASS(NullCipher, BlockCipher); REGISTER_CLASS(NullCipher, StreamCipher); void NullCiphers::registerCiphers() { - // Nothing required. + // Nothing required. } -} // namespace encfs - +} // namespace encfs diff --git a/cipher/NullCiphers.h b/cipher/NullCiphers.h index b810ac9..fd61947 100644 --- a/cipher/NullCiphers.h +++ b/cipher/NullCiphers.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -34,4 +34,3 @@ class NullCiphers { } // namespace encfs #endif - diff --git a/cipher/PBKDF.cpp b/cipher/PBKDF.cpp index 5267090..69fc650 100644 --- a/cipher/PBKDF.cpp +++ b/cipher/PBKDF.cpp @@ -4,13 +4,8 @@ namespace encfs { DEFINE_REGISTERABLE_TYPE(PBKDF) -PBKDF::PBKDF() -{ -} +PBKDF::PBKDF() {} -PBKDF::~PBKDF() -{ -} +PBKDF::~PBKDF() {} } // namespace encfs - diff --git a/cipher/PBKDF.h b/cipher/PBKDF.h index d2a00ef..7a81915 100644 --- a/cipher/PBKDF.h +++ b/cipher/PBKDF.h @@ -14,8 +14,7 @@ static const char NAME_PBKDF2_HMAC_SHA1[] = "PBKDF2_HMAC_SHA1"; static const char NAME_PBKDF2_HMAC_SHA256[] = "PBKDF2_HMAC_SHA256"; // Password Based Key Derivation Function. -class PBKDF -{ +class PBKDF { public: DECLARE_REGISTERABLE_TYPE(PBKDF); @@ -30,17 +29,17 @@ class PBKDF virtual ~PBKDF(); virtual bool makeKey(const char *password, int passwordLength, - const byte *salt, int saltLength, - int numIterations, CipherKey *outKey) = 0; + const byte *salt, int saltLength, int numIterations, + CipherKey *outKey) = 0; // Create a new key with strong randomization. - virtual CipherKey randomKey(int length) =0; + virtual CipherKey randomKey(int length) = 0; // Randomize the output. Pseudo randomization is allowed, so this may not be // used for keys or other critical values. - virtual bool pseudoRandom(byte *out, int byteLen) =0; + virtual bool pseudoRandom(byte *out, int byteLen) = 0; }; } // namespace encfs -#endif // ENCFS_PBKDF_H +#endif // ENCFS_PBKDF_H diff --git a/cipher/PBKDF_test.cpp b/cipher/PBKDF_test.cpp index 2de091a..b528be9 100644 --- a/cipher/PBKDF_test.cpp +++ b/cipher/PBKDF_test.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -19,7 +19,6 @@ * along with this program. If not, see . */ - #include #include @@ -34,23 +33,21 @@ namespace { TEST(PKCS5_PBKDF2_HMAC_SHA1, PBKDF) { Registry registry = PBKDF::GetRegistry(); - shared_ptr impl( registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA1)); + shared_ptr impl(registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA1)); ASSERT_FALSE(!impl); // Test cases from rfc6070 // Test case 1 { CipherKey key(20); - bool ok = impl->makeKey("password", 8, - (byte*)"salt", 4, - 1, &key); + bool ok = impl->makeKey("password", 8, (byte*)"salt", 4, 1, &key); ASSERT_TRUE(ok); ASSERT_EQ("0c60c80f961f0e71f3a9b524af6012062fe037a6", stringToHex(key)); } { CipherKey key(25); - bool ok = impl->makeKey("passwordPASSWORDpassword", 24, + bool ok = impl->makeKey("passwordPASSWORDpassword", 24, (byte*)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, &key); ASSERT_TRUE(ok); @@ -60,9 +57,7 @@ TEST(PKCS5_PBKDF2_HMAC_SHA1, PBKDF) { { CipherKey key(16); - bool ok = impl->makeKey("pass\0word", 9, - (byte*)"sa\0lt", 5, - 4096, &key); + bool ok = impl->makeKey("pass\0word", 9, (byte*)"sa\0lt", 5, 4096, &key); ASSERT_TRUE(ok); ASSERT_EQ("56fa6aa75548099dcc37d7f03425e0c3", stringToHex(key)); } @@ -70,48 +65,45 @@ TEST(PKCS5_PBKDF2_HMAC_SHA1, PBKDF) { TEST(PKCS5_PBKDF2_HMAC_SHA256, PBKDF) { Registry registry = PBKDF::GetRegistry(); - shared_ptr impl( - registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA256)); + shared_ptr impl(registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA256)); ASSERT_FALSE(!impl); // Test case 1 { CipherKey key(32); - bool ok = impl->makeKey("password", 8, - (byte*)"salt", 4, - 1, &key); + bool ok = impl->makeKey("password", 8, (byte*)"salt", 4, 1, &key); ASSERT_TRUE(ok); - ASSERT_EQ("120fb6cffcf8b32c" - "43e7225256c4f837" - "a86548c92ccc3548" - "0805987cb70be17b", stringToHex(key)); + ASSERT_EQ( + "120fb6cffcf8b32c" + "43e7225256c4f837" + "a86548c92ccc3548" + "0805987cb70be17b", + stringToHex(key)); } // Test case 2 { CipherKey key(40); - bool ok = impl->makeKey("passwordPASSWORDpassword", 24, + bool ok = impl->makeKey("passwordPASSWORDpassword", 24, (byte*)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, &key); ASSERT_TRUE(ok); - ASSERT_EQ("348c89dbcbd32b2f" - "32d814b8116e84cf" - "2b17347ebc180018" - "1c4e2a1fb8dd53e1" - "c635518c7dac47e9", - stringToHex(key)); + ASSERT_EQ( + "348c89dbcbd32b2f" + "32d814b8116e84cf" + "2b17347ebc180018" + "1c4e2a1fb8dd53e1" + "c635518c7dac47e9", + stringToHex(key)); } // Test case 3 { CipherKey key(16); - bool ok = impl->makeKey("pass\0word", 9, - (byte*)"sa\0lt", 5, - 4096, &key); + bool ok = impl->makeKey("pass\0word", 9, (byte*)"sa\0lt", 5, 4096, &key); ASSERT_TRUE(ok); ASSERT_EQ("89b69d0516f829893c696226650a8687", stringToHex(key)); } } } // namespace - diff --git a/cipher/StreamCipher.cpp b/cipher/StreamCipher.cpp index ef92dba..432cb78 100644 --- a/cipher/StreamCipher.cpp +++ b/cipher/StreamCipher.cpp @@ -4,13 +4,8 @@ namespace encfs { DEFINE_REGISTERABLE_TYPE(StreamCipher); -StreamCipher::StreamCipher() -{ -} +StreamCipher::StreamCipher() {} -StreamCipher::~StreamCipher() -{ -} +StreamCipher::~StreamCipher() {} } // namespace encfs - diff --git a/cipher/StreamCipher.h b/cipher/StreamCipher.h index c5c8055..0152327 100644 --- a/cipher/StreamCipher.h +++ b/cipher/StreamCipher.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -33,8 +33,7 @@ namespace encfs { static const char NAME_AES_CFB[] = "AES/CFB"; static const char NAME_BLOWFISH_CFB[] = "Blowfish/CFB"; -class StreamCipher -{ +class StreamCipher { public: DECLARE_REGISTERABLE_TYPE(StreamCipher); @@ -43,31 +42,24 @@ class StreamCipher std::string cipher; std::string mode; std::string library; - std::string toString() const { - return cipher + "/" + mode; - } + std::string toString() const { return cipher + "/" + mode; } Properties() {} Properties(Range keys, const char *cipher_, const char *mode_, - const char *library_) - : keySize(keys), - cipher(cipher_), - mode(mode_), - library(library_) { } + const char *library_) + : keySize(keys), cipher(cipher_), mode(mode_), library(library_) {} }; StreamCipher(); virtual ~StreamCipher(); - virtual bool setKey(const CipherKey& key) =0; + virtual bool setKey(const CipherKey &key) = 0; - virtual bool encrypt(const byte *ivec, const byte *in, - byte *out, int numBytes) =0; - virtual bool decrypt(const byte *ivec, const byte *in, - byte *out, int numBytes) =0; + virtual bool encrypt(const byte *ivec, const byte *in, byte *out, + int numBytes) = 0; + virtual bool decrypt(const byte *ivec, const byte *in, byte *out, + int numBytes) = 0; }; } // namespace encfs - #endif - diff --git a/cipher/botan.cpp b/cipher/botan.cpp index 177a53d..e074c67 100644 --- a/cipher/botan.cpp +++ b/cipher/botan.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -54,14 +54,11 @@ class PbkdfPkcs5Hmac : public PBKDF { public: PbkdfPkcs5Hmac(Botan::PBKDF* pbkdf) : pbkdf_(pbkdf) {} - virtual ~PbkdfPkcs5Hmac() { - delete pbkdf_; - } + virtual ~PbkdfPkcs5Hmac() { delete pbkdf_; } - virtual bool makeKey(const char *password, int passwordLength, - const byte *salt, int saltLength, - int numIterations, - CipherKey *outKey) { + virtual bool makeKey(const char* password, int passwordLength, + const byte* salt, int saltLength, int numIterations, + CipherKey* outKey) { if (pbkdf_ == NULL) { // TODO: error message return false; @@ -69,10 +66,8 @@ class PbkdfPkcs5Hmac : public PBKDF { std::string pass; pass.assign(password, passwordLength); - OctetString key = pbkdf_->derive_key(outKey->size(), - pass, - salt, saltLength, - numIterations); + OctetString key = pbkdf_->derive_key(outKey->size(), pass, salt, saltLength, + numIterations); memcpy(outKey->data(), key.begin(), outKey->size()); return true; } @@ -83,19 +78,18 @@ class PbkdfPkcs5Hmac : public PBKDF { return key; } - virtual bool pseudoRandom(byte *out, int length) { + virtual bool pseudoRandom(byte* out, int length) { rng.randomize(out, length); return true; } AutoSeeded_RNG rng; }; - + class PbkdfPkcs5HmacSha1 : public PbkdfPkcs5Hmac { public: - PbkdfPkcs5HmacSha1() - : PbkdfPkcs5Hmac( get_pbkdf("PBKDF2(SHA-1)")) { } - ~PbkdfPkcs5HmacSha1() {} + PbkdfPkcs5HmacSha1() : PbkdfPkcs5Hmac(get_pbkdf("PBKDF2(SHA-1)")) {} + ~PbkdfPkcs5HmacSha1() {} static Properties GetProperties() { Properties props; @@ -108,9 +102,8 @@ REGISTER_CLASS(PbkdfPkcs5HmacSha1, PBKDF); class PbkdfPkcs5HmacSha256 : public PbkdfPkcs5Hmac { public: - PbkdfPkcs5HmacSha256() - : PbkdfPkcs5Hmac( get_pbkdf("PBKDF2(SHA-256)")) { } - ~PbkdfPkcs5HmacSha256() {} + PbkdfPkcs5HmacSha256() : PbkdfPkcs5Hmac(get_pbkdf("PBKDF2(SHA-256)")) {} + ~PbkdfPkcs5HmacSha256() {} static Properties GetProperties() { Properties props; @@ -121,12 +114,12 @@ class PbkdfPkcs5HmacSha256 : public PbkdfPkcs5Hmac { }; REGISTER_CLASS(PbkdfPkcs5HmacSha256, PBKDF); - class BotanBlockCipher : public BlockCipher { - Keyed_Filter *encryption; // Not owned. - Keyed_Filter *decryption; // Not owned. + Keyed_Filter* encryption; // Not owned. + Keyed_Filter* decryption; // Not owned. shared_ptr encryptor; shared_ptr decryptor; + public: BotanBlockCipher() {} virtual ~BotanBlockCipher() {} @@ -147,7 +140,7 @@ class BotanBlockCipher : public BlockCipher { virtual bool encrypt(const byte* iv, const byte* in, byte* out, int size) { #ifdef HAVE_VALGRIND_MEMCHECK_H if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(in, size) != 0 || - VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, size) != 0 || + VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, size) != 0 || VALGRIND_CHECK_MEM_IS_ADDRESSABLE(iv, blockSize())) { return false; } @@ -156,9 +149,9 @@ class BotanBlockCipher : public BlockCipher { encryptor->process_msg(in, size); auto written = encryptor->read(out, size, Pipe::LAST_MESSAGE); LOG_IF(ERROR, (int)written != size) << "expected output size " << size - << ", got " << written; - LOG_IF(ERROR, encryptor->remaining() > 0) << "unread bytes in pipe: " - << encryptor->remaining(); + << ", got " << written; + LOG_IF(ERROR, encryptor->remaining() > 0) + << "unread bytes in pipe: " << encryptor->remaining(); return true; } @@ -174,9 +167,9 @@ class BotanBlockCipher : public BlockCipher { decryptor->process_msg(in, size); auto written = decryptor->read(out, size, Pipe::LAST_MESSAGE); LOG_IF(ERROR, (int)written != size) << "expected output size " << size - << ", got " << written; - LOG_IF(ERROR, decryptor->remaining() > 0) << "unread bytes in pipe: " - << decryptor->remaining(); + << ", got " << written; + LOG_IF(ERROR, decryptor->remaining() > 0) + << "unread bytes in pipe: " << decryptor->remaining(); return true; } }; @@ -192,12 +185,10 @@ class BotanAesCbc : public BotanBlockCipher { return rekey(key, ss.str()); } - virtual int blockSize() const { - return 128 >> 3; - } + virtual int blockSize() const { return 128 >> 3; } static Properties GetProperties() { - return Properties(Range(128,256,64), "AES", "CBC", "Botan"); + return Properties(Range(128, 256, 64), "AES", "CBC", "Botan"); } }; REGISTER_CLASS(BotanAesCbc, BlockCipher); @@ -213,12 +204,10 @@ class BotanAesCfb : public BotanBlockCipher { return rekey(key, ss.str()); } - virtual int blockSize() const { - return 128 >> 3; - } + virtual int blockSize() const { return 128 >> 3; } static Properties GetProperties() { - return Properties(Range(128,256,64), "AES", "CFB", "Botan"); + return Properties(Range(128, 256, 64), "AES", "CFB", "Botan"); } }; REGISTER_CLASS(BotanAesCfb, StreamCipher); @@ -230,16 +219,15 @@ class BotanBlowfishCbc : public BotanBlockCipher { virtual bool setKey(const CipherKey& key) { std::ostringstream ss; - ss << "Blowfish" << "/CBC/NoPadding"; + ss << "Blowfish" + << "/CBC/NoPadding"; return rekey(key, ss.str()); } - virtual int blockSize() const { - return 64 >> 3; - } + virtual int blockSize() const { return 64 >> 3; } static Properties GetProperties() { - return Properties(Range(128,256,32), "Blowfish", "CBC", "Botan"); + return Properties(Range(128, 256, 32), "Blowfish", "CBC", "Botan"); } }; REGISTER_CLASS(BotanBlowfishCbc, BlockCipher); @@ -251,49 +239,42 @@ class BotanBlowfishCfb : public BotanBlockCipher { virtual bool setKey(const CipherKey& key) { std::ostringstream ss; - ss << "Blowfish" << "/CFB"; + ss << "Blowfish" + << "/CFB"; return rekey(key, ss.str()); } - virtual int blockSize() const { - return 64 >> 3; - } + virtual int blockSize() const { return 64 >> 3; } static Properties GetProperties() { - return Properties(Range(128,256,32), "Blowfish", "CFB", "Botan"); + return Properties(Range(128, 256, 32), "Blowfish", "CFB", "Botan"); } }; REGISTER_CLASS(BotanBlowfishCfb, StreamCipher); - class Sha1HMac : public MAC { - MessageAuthenticationCode *mac; + MessageAuthenticationCode* mac; public: Sha1HMac() : mac(Botan::get_mac("HMAC(SHA-1)")) {} - virtual ~Sha1HMac() { - delete mac; - } + virtual ~Sha1HMac() { delete mac; } - virtual int outputSize() const { - return mac->output_length(); - } + virtual int outputSize() const { return mac->output_length(); } - virtual bool setKey(const CipherKey &key) { + virtual bool setKey(const CipherKey& key) { SymmetricKey bkey(key.data(), key.size()); mac->set_key(bkey); return true; } - virtual void init() { - } + virtual void init() {} - virtual bool update(const byte *in, int length) { + virtual bool update(const byte* in, int length) { mac->update(in, length); return true; } - virtual bool write(byte *out) { + virtual bool write(byte* out) { #ifdef HAVE_VALGRIND_MEMCHECK_H if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, outputSize()) != 0) { return false; @@ -336,4 +317,3 @@ void Botan_registerCiphers() { } } // namespace encfs - diff --git a/cipher/botan.h b/cipher/botan.h index b3f5eea..cb82b88 100644 --- a/cipher/botan.h +++ b/cipher/botan.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -33,4 +33,3 @@ extern void Botan_registerCiphers(); } // namespace encfs #endif - diff --git a/cipher/openssl.cpp b/cipher/openssl.cpp index 2cbb1ea..71f0ed6 100644 --- a/cipher/openssl.cpp +++ b/cipher/openssl.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -59,53 +59,48 @@ namespace encfs { -const int MAX_KEYLENGTH = 64; // in bytes (256 bit) +const int MAX_KEYLENGTH = 64; // in bytes (256 bit) const int MAX_IVLENGTH = 16; const int KEY_CHECKSUM_BYTES = 4; #ifndef MIN -inline int MIN(int a, int b) -{ - return (a < b) ? a : b; -} +inline int MIN(int a, int b) { return (a < b) ? a : b; } #endif - // Base for {Block,Stream}Cipher implementation. class OpenSSLCipher : public BlockCipher { public: OpenSSLCipher() { - EVP_CIPHER_CTX_init( &enc ); - EVP_CIPHER_CTX_init( &dec ); + EVP_CIPHER_CTX_init(&enc); + EVP_CIPHER_CTX_init(&dec); } virtual ~OpenSSLCipher() { - EVP_CIPHER_CTX_cleanup( &enc ); - EVP_CIPHER_CTX_cleanup( &dec ); + EVP_CIPHER_CTX_cleanup(&enc); + EVP_CIPHER_CTX_cleanup(&dec); } bool rekey(const EVP_CIPHER *cipher, const CipherKey &key) { VLOG(1) << "setting key length " << key.size(); - EVP_EncryptInit_ex( &enc, cipher, NULL, NULL, NULL); - EVP_CIPHER_CTX_set_key_length( &enc, key.size() ); - EVP_CIPHER_CTX_set_padding( &enc, 0 ); - EVP_EncryptInit_ex( &enc, NULL, NULL, key.data(), NULL); + EVP_EncryptInit_ex(&enc, cipher, NULL, NULL, NULL); + EVP_CIPHER_CTX_set_key_length(&enc, key.size()); + EVP_CIPHER_CTX_set_padding(&enc, 0); + EVP_EncryptInit_ex(&enc, NULL, NULL, key.data(), NULL); - EVP_DecryptInit_ex( &dec, cipher, NULL, NULL, NULL); - EVP_CIPHER_CTX_set_key_length( &dec, key.size() ); - EVP_CIPHER_CTX_set_padding( &dec, 0 ); - EVP_DecryptInit_ex( &dec, NULL, NULL, key.data(), NULL); + EVP_DecryptInit_ex(&dec, cipher, NULL, NULL, NULL); + EVP_CIPHER_CTX_set_key_length(&dec, key.size()); + EVP_CIPHER_CTX_set_padding(&dec, 0); + EVP_DecryptInit_ex(&dec, NULL, NULL, key.data(), NULL); return true; } static bool randomize(CipherKey *key) { - int result = RAND_bytes( key->data(), key->size() ); - if(result != 1) - { - char errStr[120]; // specs require string at least 120 bytes long.. + int result = RAND_bytes(key->data(), key->size()); + if (result != 1) { + char errStr[120]; // specs require string at least 120 bytes long.. unsigned long errVal = 0; - if((errVal = ERR_get_error()) != 0) - LOG(ERROR) << "openssl error: " << ERR_error_string( errVal, errStr ); + if ((errVal = ERR_get_error()) != 0) + LOG(ERROR) << "openssl error: " << ERR_error_string(errVal, errStr); return false; } @@ -114,20 +109,19 @@ class OpenSSLCipher : public BlockCipher { #endif return true; } - + static bool pseudoRandomize(byte *out, int length) { #ifdef HAVE_VALGRIND_MEMCHECK_H if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, length) != 0) { return false; } #endif - int result = RAND_pseudo_bytes( out, length ); - if(result != 1) - { - char errStr[120]; // specs require string at least 120 bytes long.. + int result = RAND_pseudo_bytes(out, length); + if (result != 1) { + char errStr[120]; // specs require string at least 120 bytes long.. unsigned long errVal = 0; - if((errVal = ERR_get_error()) != 0) - LOG(ERROR) << "openssl error: " << ERR_error_string( errVal, errStr ); + if ((errVal = ERR_get_error()) != 0) + LOG(ERROR) << "openssl error: " << ERR_error_string(errVal, errStr); return false; } @@ -141,8 +135,7 @@ class OpenSSLCipher : public BlockCipher { bool rekey(const EVP_CIPHER *cipher, int keyLength) { CipherKey key(keyLength); - if (!randomize(&key)) - return false; + if (!randomize(&key)) return false; return rekey(cipher, key); } @@ -150,13 +143,11 @@ class OpenSSLCipher : public BlockCipher { virtual int blockSize() const { int len = EVP_CIPHER_CTX_block_size(&enc); // Some versions of OpenSSL report 1 for block size os AES_XTS.. - if (len == 1) - len = EVP_CIPHER_CTX_key_length(&enc); + if (len == 1) len = EVP_CIPHER_CTX_key_length(&enc); return len; } - virtual bool encrypt(const byte *ivec, const byte *in, - byte *out, int size) { + virtual bool encrypt(const byte *ivec, const byte *in, byte *out, int size) { int dstLen = 0, tmpLen = 0; #ifdef HAVE_VALGRIND_MEMCHECK_H int ivLen = EVP_CIPHER_CTX_iv_length(&enc); @@ -169,22 +160,21 @@ class OpenSSLCipher : public BlockCipher { return false; } #endif - EVP_EncryptInit_ex( &enc, NULL, NULL, NULL, ivec); - EVP_EncryptUpdate( &enc, out, &dstLen, in, size); - EVP_EncryptFinal_ex( &enc, out+dstLen, &tmpLen ); + EVP_EncryptInit_ex(&enc, NULL, NULL, NULL, ivec); + EVP_EncryptUpdate(&enc, out, &dstLen, in, size); + EVP_EncryptFinal_ex(&enc, out + dstLen, &tmpLen); dstLen += tmpLen; if (dstLen != size) { - LOG(ERROR) << "encoding " << size - << " bytes, got back " << dstLen << " (" << tmpLen << " in final_ex)"; + LOG(ERROR) << "encoding " << size << " bytes, got back " << dstLen << " (" + << tmpLen << " in final_ex)"; return false; } return true; } - virtual bool decrypt(const byte *ivec, const byte *in, - byte *out, int size) { + virtual bool decrypt(const byte *ivec, const byte *in, byte *out, int size) { int dstLen = 0, tmpLen = 0; #ifdef HAVE_VALGRIND_MEMCHECK_H int ivLen = EVP_CIPHER_CTX_iv_length(&enc); @@ -197,14 +187,14 @@ class OpenSSLCipher : public BlockCipher { return false; } #endif - EVP_DecryptInit_ex( &dec, NULL, NULL, NULL, ivec); - EVP_DecryptUpdate( &dec, out, &dstLen, in, size ); - EVP_DecryptFinal_ex( &dec, out+dstLen, &tmpLen ); + EVP_DecryptInit_ex(&dec, NULL, NULL, NULL, ivec); + EVP_DecryptUpdate(&dec, out, &dstLen, in, size); + EVP_DecryptFinal_ex(&dec, out + dstLen, &tmpLen); dstLen += tmpLen; if (dstLen != size) { - LOG(ERROR) << "decoding " << size - << " bytes, got back " << dstLen << " (" << tmpLen << " in final_ex)"; + LOG(ERROR) << "decoding " << size << " bytes, got back " << dstLen << " (" + << tmpLen << " in final_ex)"; return false; } @@ -216,9 +206,8 @@ class OpenSSLCipher : public BlockCipher { EVP_CIPHER_CTX dec; }; - #if defined(HAVE_EVP_BF) -static Range BfKeyRange(128,256,32); +static Range BfKeyRange(128, 256, 32); class BfCbcBlockCipher : public OpenSSLCipher { public: BfCbcBlockCipher() {} @@ -263,28 +252,29 @@ class BfCfbStreamCipher : public OpenSSLCipher { REGISTER_CLASS(BfCfbStreamCipher, StreamCipher); #endif - #if defined(HAVE_EVP_AES) -static Range AesKeyRange(128,256,64); +static Range AesKeyRange(128, 256, 64); class AesCbcBlockCipher : public OpenSSLCipher { public: AesCbcBlockCipher() {} virtual ~AesCbcBlockCipher() {} - virtual bool setKey(const CipherKey& key) { + virtual bool setKey(const CipherKey &key) { const EVP_CIPHER *cipher = getCipher(key.size()); return (cipher != NULL) && rekey(cipher, key); } static const EVP_CIPHER *getCipher(int keyLength) { - switch(keyLength * 8) - { - case 128: return EVP_aes_128_cbc(); - case 192: return EVP_aes_192_cbc(); - case 256: return EVP_aes_256_cbc(); + switch (keyLength * 8) { + case 128: + return EVP_aes_128_cbc(); + case 192: + return EVP_aes_192_cbc(); + case 256: + return EVP_aes_256_cbc(); default: - LOG(INFO) << "Unsupported key length: " << keyLength; - return NULL; + LOG(INFO) << "Unsupported key length: " << keyLength; + return NULL; } } @@ -304,20 +294,22 @@ class AesCfbStreamCipher : public OpenSSLCipher { AesCfbStreamCipher() {} virtual ~AesCfbStreamCipher() {} - virtual bool setKey(const CipherKey& key) { + virtual bool setKey(const CipherKey &key) { const EVP_CIPHER *cipher = getCipher(key.size()); return (cipher != NULL) && rekey(cipher, key); } static const EVP_CIPHER *getCipher(int keyLength) { - switch(keyLength * 8) - { - case 128: return EVP_aes_128_cfb(); - case 192: return EVP_aes_192_cfb(); - case 256: return EVP_aes_256_cfb(); + switch (keyLength * 8) { + case 128: + return EVP_aes_128_cfb(); + case 192: + return EVP_aes_192_cfb(); + case 256: + return EVP_aes_256_cfb(); default: - LOG(INFO) << "Unsupported key length: " << keyLength; - return NULL; + LOG(INFO) << "Unsupported key length: " << keyLength; + return NULL; } } @@ -334,7 +326,7 @@ REGISTER_CLASS(AesCfbStreamCipher, StreamCipher); #endif #if defined(HAVE_EVP_AES_XTS) -static Range AesXtsKeyRange(128,256,128); +static Range AesXtsKeyRange(128, 256, 128); class AesXtsBlockCipher : public OpenSSLCipher { public: AesXtsBlockCipher() {} @@ -346,11 +338,13 @@ class AesXtsBlockCipher : public OpenSSLCipher { } static const EVP_CIPHER *getCipher(int keyLength) { - switch(keyLength * 8) - { - case 128: return EVP_aes_128_xts(); - case 256: return EVP_aes_256_xts(); - default: return NULL; + switch (keyLength * 8) { + case 128: + return EVP_aes_128_xts(); + case 256: + return EVP_aes_256_xts(); + default: + return NULL; } } @@ -368,15 +362,11 @@ REGISTER_CLASS(AesXtsBlockCipher, BlockCipher); class Sha1HMac : public MAC { public: - Sha1HMac() { - HMAC_CTX_init(&ctx); - } - virtual ~Sha1HMac() { - HMAC_CTX_cleanup(&ctx); - } + Sha1HMac() { HMAC_CTX_init(&ctx); } + virtual ~Sha1HMac() { HMAC_CTX_cleanup(&ctx); } virtual int outputSize() const { - return 20; // 160 bit. + return 20; // 160 bit. } virtual bool setKey(const CipherKey &key) { @@ -384,10 +374,8 @@ class Sha1HMac : public MAC { return true; } - virtual void init() { - HMAC_Init_ex(&ctx, 0, 0, 0, 0); - } - + virtual void init() { HMAC_Init_ex(&ctx, 0, 0, 0, 0); } + virtual bool update(const byte *in, int length) { HMAC_Update(&ctx, in, length); return true; @@ -416,31 +404,28 @@ class Sha1HMac : public MAC { props.library = "OpenSSL"; return props; } + private: HMAC_CTX ctx; }; REGISTER_CLASS(Sha1HMac, MAC); - class PbkdfPkcs5HmacSha1 : public PBKDF { public: PbkdfPkcs5HmacSha1() {} virtual ~PbkdfPkcs5HmacSha1() {} virtual bool makeKey(const char *password, int passwordLength, - const byte *salt, int saltLength, - int numIterations, + const byte *salt, int saltLength, int numIterations, CipherKey *outKey) { return PKCS5_PBKDF2_HMAC_SHA1( - password, passwordLength, - const_cast(salt), saltLength, - numIterations, outKey->size(), outKey->data()) == 1; + password, passwordLength, const_cast(salt), saltLength, + numIterations, outKey->size(), outKey->data()) == 1; } virtual CipherKey randomKey(int length) { CipherKey key(length); - if (!OpenSSLCipher::randomize(&key)) - key.reset(); + if (!OpenSSLCipher::randomize(&key)) key.reset(); return key; } @@ -463,20 +448,16 @@ class PbkdfPkcs5HmacSha256 : public PBKDF { virtual ~PbkdfPkcs5HmacSha256() {} virtual bool makeKey(const char *password, int passwordLength, - const byte *salt, int saltLength, - int numIterations, + const byte *salt, int saltLength, int numIterations, CipherKey *outKey) { - return PKCS5_PBKDF2_HMAC( - password, passwordLength, - const_cast(salt), saltLength, - numIterations, EVP_sha256(), - outKey->size(), outKey->data()) == 1; + return PKCS5_PBKDF2_HMAC(password, passwordLength, const_cast(salt), + saltLength, numIterations, EVP_sha256(), + outKey->size(), outKey->data()) == 1; } virtual CipherKey randomKey(int length) { CipherKey key(length); - if (!OpenSSLCipher::randomize(&key)) - key.reset(); + if (!OpenSSLCipher::randomize(&key)) key.reset(); return key; } @@ -493,85 +474,70 @@ class PbkdfPkcs5HmacSha256 : public PBKDF { }; REGISTER_CLASS(PbkdfPkcs5HmacSha256, PBKDF); - -unsigned long pthreads_thread_id() -{ - return (unsigned long)pthread_self(); -} +unsigned long pthreads_thread_id() { return (unsigned long)pthread_self(); } static pthread_mutex_t *crypto_locks = NULL; -void pthreads_locking_callback( int mode, int n, - const char *caller_file, int caller_line ) -{ +void pthreads_locking_callback(int mode, int n, const char *caller_file, + int caller_line) { (void)caller_file; (void)caller_line; - if(!crypto_locks) - { + if (!crypto_locks) { VLOG(1) << "Allocating " << CRYPTO_num_locks() << " locks for OpenSSL"; - crypto_locks = new pthread_mutex_t[ CRYPTO_num_locks() ]; - for(int i=0; i @@ -28,7 +29,8 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; +static const char rcsid[] = + "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; #endif /* LIBC_SCCS and not lint */ //#include "includes.h" @@ -50,134 +52,126 @@ static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41: #include "cipher/readpassphrase.h" #ifdef TCSASOFT -# define _T_FLUSH (TCSAFLUSH|TCSASOFT) +#define _T_FLUSH (TCSAFLUSH | TCSASOFT) #else -# define _T_FLUSH (TCSAFLUSH) +#define _T_FLUSH (TCSAFLUSH) #endif /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ #if !defined(_POSIX_VDISABLE) && defined(VDISABLE) -# define _POSIX_VDISABLE VDISABLE +#define _POSIX_VDISABLE VDISABLE #endif static volatile sig_atomic_t signo; static void handler(int); -char * -readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) -{ - ssize_t nr; - int input, output, save_errno; - char ch, *p, *end; - struct termios term, oterm; - struct sigaction sa, saveint, savehup, savequit, saveterm; - struct sigaction savetstp, savettin, savettou; +char *readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { + ssize_t nr; + int input, output, save_errno; + char ch, *p, *end; + struct termios term, oterm; + struct sigaction sa, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou; - /* I suppose we could alloc on demand in this case (XXX). */ - if (bufsiz == 0) { - errno = EINVAL; - return(NULL); - } + /* I suppose we could alloc on demand in this case (XXX). */ + if (bufsiz == 0) { + errno = EINVAL; + return (NULL); + } restart: - /* - * Read and write to /dev/tty if available. If not, read from - * stdin and write to stderr unless a tty is required. - */ - if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { - if (flags & RPP_REQUIRE_TTY) { - errno = ENOTTY; - return(NULL); - } - input = STDIN_FILENO; - output = STDERR_FILENO; - } + /* + * Read and write to /dev/tty if available. If not, read from + * stdin and write to stderr unless a tty is required. + */ + if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return (NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } - /* - * Catch signals that would otherwise cause the user to end - * up with echo turned off in the shell. Don't worry about - * things like SIGALRM and SIGPIPE for now. - */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; /* don't restart system calls */ - sa.sa_handler = handler; - (void)sigaction(SIGINT, &sa, &saveint); - (void)sigaction(SIGHUP, &sa, &savehup); - (void)sigaction(SIGQUIT, &sa, &savequit); - (void)sigaction(SIGTERM, &sa, &saveterm); - (void)sigaction(SIGTSTP, &sa, &savetstp); - (void)sigaction(SIGTTIN, &sa, &savettin); - (void)sigaction(SIGTTOU, &sa, &savettou); + /* + * Catch signals that would otherwise cause the user to end + * up with echo turned off in the shell. Don't worry about + * things like SIGALRM and SIGPIPE for now. + */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; /* don't restart system calls */ + sa.sa_handler = handler; + (void)sigaction(SIGINT, &sa, &saveint); + (void)sigaction(SIGHUP, &sa, &savehup); + (void)sigaction(SIGQUIT, &sa, &savequit); + (void)sigaction(SIGTERM, &sa, &saveterm); + (void)sigaction(SIGTSTP, &sa, &savetstp); + (void)sigaction(SIGTTIN, &sa, &savettin); + (void)sigaction(SIGTTOU, &sa, &savettou); - /* Turn off echo if possible. */ - if (tcgetattr(input, &oterm) == 0) { - memcpy(&term, &oterm, sizeof(term)); - if (!(flags & RPP_ECHO_ON)) - term.c_lflag &= ~(ECHO | ECHONL); + /* Turn off echo if possible. */ + if (tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) term.c_lflag &= ~(ECHO | ECHONL); #ifdef VSTATUS - if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) - term.c_cc[VSTATUS] = _POSIX_VDISABLE; + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; #endif - (void)tcsetattr(input, _T_FLUSH, &term); - } else { - memset(&term, 0, sizeof(term)); - memset(&oterm, 0, sizeof(oterm)); - } + (void)tcsetattr(input, _T_FLUSH, &term); + } else { + memset(&term, 0, sizeof(term)); + memset(&oterm, 0, sizeof(oterm)); + } - (void)write(output, prompt, strlen(prompt)); - end = buf + bufsiz - 1; - for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { - if (p < end) { - if ((flags & RPP_SEVENBIT)) - ch &= 0x7f; - if (isalpha(ch)) { - if ((flags & RPP_FORCELOWER)) - ch = tolower(ch); - if ((flags & RPP_FORCEUPPER)) - ch = toupper(ch); - } - *p++ = ch; - } - } - *p = '\0'; - save_errno = errno; - if (!(term.c_lflag & ECHO)) - (void)write(output, "\n", 1); + (void)write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { + if (p < end) { + if ((flags & RPP_SEVENBIT)) ch &= 0x7f; + if (isalpha(ch)) { + if ((flags & RPP_FORCELOWER)) ch = tolower(ch); + if ((flags & RPP_FORCEUPPER)) ch = toupper(ch); + } + *p++ = ch; + } + } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) (void)write(output, "\n", 1); - /* Restore old terminal settings and signals. */ - if (memcmp(&term, &oterm, sizeof(term)) != 0) - (void)tcsetattr(input, _T_FLUSH, &oterm); - (void)sigaction(SIGINT, &saveint, NULL); - (void)sigaction(SIGHUP, &savehup, NULL); - (void)sigaction(SIGQUIT, &savequit, NULL); - (void)sigaction(SIGTERM, &saveterm, NULL); - (void)sigaction(SIGTSTP, &savetstp, NULL); - (void)sigaction(SIGTTIN, &savettin, NULL); - (void)sigaction(SIGTTOU, &savettou, NULL); - if (input != STDIN_FILENO) - (void)close(input); + /* Restore old terminal settings and signals. */ + if (memcmp(&term, &oterm, sizeof(term)) != 0) + (void)tcsetattr(input, _T_FLUSH, &oterm); + (void)sigaction(SIGINT, &saveint, NULL); + (void)sigaction(SIGHUP, &savehup, NULL); + (void)sigaction(SIGQUIT, &savequit, NULL); + (void)sigaction(SIGTERM, &saveterm, NULL); + (void)sigaction(SIGTSTP, &savetstp, NULL); + (void)sigaction(SIGTTIN, &savettin, NULL); + (void)sigaction(SIGTTOU, &savettou, NULL); + if (input != STDIN_FILENO) (void)close(input); - /* - * If we were interrupted by a signal, resend it to ourselves - * now that we have restored the signal handlers. - */ - if (signo) { - kill(getpid(), signo); - switch (signo) { - case SIGTSTP: - case SIGTTIN: - case SIGTTOU: - signo = 0; - goto restart; - } - } + /* + * If we were interrupted by a signal, resend it to ourselves + * now that we have restored the signal handlers. + */ + if (signo) { + kill(getpid(), signo); + switch (signo) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + signo = 0; + goto restart; + } + } - errno = save_errno; - return(nr == -1 ? NULL : buf); + errno = save_errno; + return (nr == -1 ? NULL : buf); } #endif /* HAVE_READPASSPHRASE */ - + #if 0 char * getpass(const char *prompt) @@ -188,8 +182,4 @@ getpass(const char *prompt) } #endif -static void handler(int s) -{ - - signo = s; -} +static void handler(int s) { signo = s; } diff --git a/cipher/readpassphrase.h b/cipher/readpassphrase.h index e17db34..eed8674 100644 --- a/cipher/readpassphrase.h +++ b/cipher/readpassphrase.h @@ -1,4 +1,5 @@ -/* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ */ +/* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ + */ /* * Copyright (c) 2000 Todd C. Miller @@ -35,17 +36,19 @@ #ifndef HAVE_READPASSPHRASE -#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ -#define RPP_ECHO_ON 0x01 /* Leave echo on. */ -#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ -#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ -#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ -#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ #ifdef __cplusplus extern "C" #endif -char *readpassphrase(const char *prompt, char *buf, size_t bufSize, int flags); + char * + readpassphrase(const char *prompt, char *buf, size_t bufSize, + int flags); #endif /* HAVE_READPASSPHRASE */ diff --git a/cipher/testing.cpp b/cipher/testing.cpp index 1ed5649..c82e745 100644 --- a/cipher/testing.cpp +++ b/cipher/testing.cpp @@ -35,7 +35,7 @@ void setDataFromHex(byte *out, int len, const char *hex) { unsigned int last = 0; while (len > 0 && *hex != '\0') { byte nibble = *hex++; - if (nibble >= '0' && nibble <= '9') + if (nibble >= '0' && nibble <= '9') nibble -= '0'; else if (nibble >= 'A' && nibble <= 'F') nibble -= 'A' - 10; @@ -64,4 +64,3 @@ int main(int argc, char **argv) { } } // namespace encfs - diff --git a/cipher/testing.h b/cipher/testing.h index 484e36b..4c8eade 100644 --- a/cipher/testing.h +++ b/cipher/testing.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -31,7 +31,7 @@ namespace encfs { std::string stringToHex(const byte *data, int len); template -std::string stringToHex(const T& value) { +std::string stringToHex(const T &value) { return stringToHex(value.data(), value.size()); } @@ -40,4 +40,3 @@ void setDataFromHex(byte *out, int size, const char *hex); } // namespace encfs #endif - diff --git a/encfs/main.cpp b/encfs/main.cpp index 8a071ef..90c7783 100644 --- a/encfs/main.cpp +++ b/encfs/main.cpp @@ -54,10 +54,7 @@ extern "C" void fuse_unmount_compat22(const char *mountpoint); #define fuse_unmount fuse_unmount_compat22 #ifndef MAX -inline static int MAX(int a, int b) -{ - return (a > b) ? a : b; -} +inline static int MAX(int a, int b) { return (a > b) ? a : b; } #endif using namespace encfs; @@ -72,13 +69,12 @@ namespace encfs { // Maximum number of arguments that we're going to pass on to fuse. Doesn't // affect how many arguments we can handle, just how many we can pass on.. const int MaxFuseArgs = 32; -struct EncFS_Args -{ - string mountPoint; // where to make filesystem visible - bool isDaemon; // true == spawn in background, log to syslog - bool isThreaded; // true == threaded - bool isVerbose; // false == only enable warning/error messages - int idleTimeout; // 0 == idle time in minutes to trigger unmount +struct EncFS_Args { + string mountPoint; // where to make filesystem visible + bool isDaemon; // true == spawn in background, log to syslog + bool isThreaded; // true == threaded + bool isVerbose; // false == only enable warning/error messages + int idleTimeout; // 0 == idle time in minutes to trigger unmount const char *fuseArgv[MaxFuseArgs]; int fuseArgc; @@ -88,103 +84,98 @@ struct EncFS_Args // In case someone sends me a log dump, I want to know how what options are // in effect. Not internationalized, since it is something that is mostly // useful for me! - string toString() - { + string toString() { ostringstream ss; ss << (isDaemon ? "(daemon) " : "(fg) "); ss << (isThreaded ? "(threaded) " : "(UP) "); - if(idleTimeout > 0) - ss << "(timeout " << idleTimeout << ") "; - if(opts->checkKey) ss << "(keyCheck) "; - if(opts->forceDecode) ss << "(forceDecode) "; - if(opts->ownerCreate) ss << "(ownerCreate) "; - if(opts->useStdin) ss << "(useStdin) "; - if(opts->annotate) ss << "(annotate) "; - if(opts->reverseEncryption) ss << "(reverseEncryption) "; - if(opts->mountOnDemand) ss << "(mountOnDemand) "; - if(opts->delayMount) ss << "(delayMount) "; - for(int i=0; i 0) ss << "(timeout " << idleTimeout << ") "; + if (opts->checkKey) ss << "(keyCheck) "; + if (opts->forceDecode) ss << "(forceDecode) "; + if (opts->ownerCreate) ss << "(ownerCreate) "; + if (opts->useStdin) ss << "(useStdin) "; + if (opts->annotate) ss << "(annotate) "; + if (opts->reverseEncryption) ss << "(reverseEncryption) "; + if (opts->mountOnDemand) ss << "(mountOnDemand) "; + if (opts->delayMount) ss << "(delayMount) "; + for (int i = 0; i < fuseArgc; ++i) ss << fuseArgv[i] << ' '; return ss.str(); } - EncFS_Args() - : opts( new EncFS_Opts() ) - { - } + EncFS_Args() : opts(new EncFS_Opts()) {} }; static int oldStderr = STDERR_FILENO; } // namespace encfs -static -void usage(const char *name) -{ +static void usage(const char *name) { // xgroup(usage) - cerr << autosprintf( _("Build: encfs version %s"), VERSION ) - << "\n\n" - // xgroup(usage) - << autosprintf(_("Usage: %s [options] rootDir mountPoint [-- [FUSE Mount Options]]"), name) << "\n\n" - // xgroup(usage) - << _("Common Options:\n" - " -H\t\t\t" "show optional FUSE Mount Options\n" - " -s\t\t\t" "disable multithreaded operation\n" - " -f\t\t\t" "run in foreground (don't spawn daemon).\n" - "\t\t\tError messages will be sent to stderr\n" - "\t\t\tinstead of syslog.\n") + cerr << autosprintf(_("Build: encfs version %s"), VERSION) << "\n\n" + // xgroup(usage) + << autosprintf(_("Usage: %s [options] rootDir mountPoint [-- [FUSE " + "Mount Options]]"), + name) << "\n\n" + // xgroup(usage) + << _("Common Options:\n" + " -H\t\t\t" + "show optional FUSE Mount Options\n" + " -s\t\t\t" + "disable multithreaded operation\n" + " -f\t\t\t" + "run in foreground (don't spawn daemon).\n" + "\t\t\tError messages will be sent to stderr\n" + "\t\t\tinstead of syslog.\n") - // xgroup(usage) - << _(" -v, --verbose\t\t" "verbose: output encfs debug messages\n" - " -i, --idle=MINUTES\t""Auto unmount after period of inactivity\n" - " --anykey\t\t" "Do not verify correct key is being used\n" - " --forcedecode\t\t" "decode data even if an error is detected\n" - "\t\t\t(for filesystems using MAC block headers)\n") - << _(" --public\t\t" "act as a typical multi-user filesystem\n" - "\t\t\t(encfs must be run as root)\n") - << _(" --reverse\t\t" "reverse encryption\n") + // xgroup(usage) + << _(" -v, --verbose\t\t" + "verbose: output encfs debug messages\n" + " -i, --idle=MINUTES\t" + "Auto unmount after period of inactivity\n" + " --anykey\t\t" + "Do not verify correct key is being used\n" + " --forcedecode\t\t" + "decode data even if an error is detected\n" + "\t\t\t(for filesystems using MAC block headers)\n") + << _(" --public\t\t" + "act as a typical multi-user filesystem\n" + "\t\t\t(encfs must be run as root)\n") << _(" --reverse\t\t" + "reverse encryption\n") - // xgroup(usage) - << _(" --extpass=program\tUse external program for password prompt\n" - "\n" - "Example, to mount at ~/crypt with raw storage in ~/.crypt :\n" - " encfs ~/.crypt ~/crypt\n" - "\n") - // xgroup(usage) - << _("For more information, see the man page encfs(1)") << "\n" - << endl; + // xgroup(usage) + << _(" --extpass=program\tUse external program for password prompt\n" + "\n" + "Example, to mount at ~/crypt with raw storage in ~/.crypt :\n" + " encfs ~/.crypt ~/crypt\n" + "\n") + // xgroup(usage) + << _("For more information, see the man page encfs(1)") << "\n" << endl; } -static -void FuseUsage() -{ +static void FuseUsage() { // xgroup(usage) cerr << _("encfs [options] rootDir mountPoint -- [FUSE Mount Options]\n" - "valid FUSE Mount Options follow:\n") << endl; + "valid FUSE Mount Options follow:\n") << endl; int argc = 2; const char *argv[] = {"...", "-h"}; - fuse_main( argc, const_cast(argv), (fuse_operations*)NULL, NULL); + fuse_main(argc, const_cast(argv), (fuse_operations *)NULL, NULL); } -#define PUSHARG(ARG) do { \ - rAssert(out->fuseArgc < MaxFuseArgs); \ - out->fuseArgv[out->fuseArgc++] = (ARG); } \ -while(0) +#define PUSHARG(ARG) \ + do { \ + rAssert(out->fuseArgc < MaxFuseArgs); \ + out->fuseArgv[out->fuseArgc++] = (ARG); \ + } while (0) -static -string slashTerminate( const string &src ) -{ +static string slashTerminate(const string &src) { string result = src; - if( result[ result.length()-1 ] != '/' ) - result.append( "/" ); + if (result[result.length() - 1] != '/') result.append("/"); return result; } -static -bool processArgs(int argc, char *argv[], const shared_ptr &out) -{ +static bool processArgs(int argc, char *argv[], + const shared_ptr &out) { // set defaults out->isDaemon = true; out->isThreaded = true; @@ -212,30 +203,28 @@ bool processArgs(int argc, char *argv[], const shared_ptr &out) // TODO: can flags be internationalized? static struct option long_options[] = { - {"fuse-debug", 0, 0, 'd'}, // Fuse debug mode - {"forcedecode", 0, 0, 'D'}, // force decode - // {"foreground", 0, 0, 'f'}, // foreground mode (no daemon) - {"fuse-help", 0, 0, 'H'}, // fuse_mount usage - {"idle", 1, 0, 'i'}, // idle timeout - {"anykey", 0, 0, 'k'}, // skip key checks - {"no-default-flags", 0, 0, 'N'}, // don't use default fuse flags - {"ondemand", 0, 0, 'm'}, // mount on-demand - {"delaymount", 0, 0, 'M'}, // delay initial mount until use - {"public", 0, 0, 'P'}, // public mode - {"extpass", 1, 0, 'p'}, // external password program - // {"single-thread", 0, 0, 's'}, // single-threaded mode - {"stdinpass", 0, 0, 'S'}, // read password from stdin - {"annotate", 0, 0, 513}, // Print annotation lines to stderr - {"verbose", 0, 0, 'v'}, // verbose mode - {"version", 0, 0, 'V'}, //version - {"reverse", 0, 0, 'r'}, // reverse encryption - {"standard", 0, 0, '1'}, // standard configuration - {"paranoia", 0, 0, '2'}, // standard configuration - {0,0,0,0} - }; + {"fuse-debug", 0, 0, 'd'}, // Fuse debug mode + {"forcedecode", 0, 0, 'D'}, // force decode + // {"foreground", 0, 0, 'f'}, // foreground mode (no daemon) + {"fuse-help", 0, 0, 'H'}, // fuse_mount usage + {"idle", 1, 0, 'i'}, // idle timeout + {"anykey", 0, 0, 'k'}, // skip key checks + {"no-default-flags", 0, 0, 'N'}, // don't use default fuse flags + {"ondemand", 0, 0, 'm'}, // mount on-demand + {"delaymount", 0, 0, 'M'}, // delay initial mount until use + {"public", 0, 0, 'P'}, // public mode + {"extpass", 1, 0, 'p'}, // external password program + // {"single-thread", 0, 0, 's'}, // single-threaded mode + {"stdinpass", 0, 0, 'S'}, // read password from stdin + {"annotate", 0, 0, 513}, // Print annotation lines to stderr + {"verbose", 0, 0, 'v'}, // verbose mode + {"version", 0, 0, 'V'}, // version + {"reverse", 0, 0, 'r'}, // reverse encryption + {"standard", 0, 0, '1'}, // standard configuration + {"paranoia", 0, 0, '2'}, // standard configuration + {0, 0, 0, 0}}; - while (1) - { + while (1) { int option_index = 0; // 's' : single-threaded mode @@ -246,107 +235,102 @@ bool processArgs(int argc, char *argv[], const shared_ptr &out) // 'm' : mount-on-demand // 'S' : password from stdin // 'o' : arguments meant for fuse - int res = getopt_long( argc, argv, "HsSfvVdmi:o:", - long_options, &option_index); + int res = + getopt_long(argc, argv, "HsSfvVdmi:o:", long_options, &option_index); - if(res == -1) - break; + if (res == -1) break; - switch( res ) - { - case '1': - out->opts->configMode = Config_Standard; - break; - case '2': - out->opts->configMode = Config_Paranoia; - break; - case 's': - out->isThreaded = false; - break; - case 'S': - out->opts->useStdin = true; - break; - case 513: - out->opts->annotate = true; - break; - case 'f': - out->isDaemon = false; - // this option was added in fuse 2.x - PUSHARG("-f"); - break; - case 'v': - out->isVerbose = true; - break; - case 'd': - PUSHARG("-d"); - break; - case 'i': - out->idleTimeout = strtol( optarg, (char**)NULL, 10); - out->opts->idleTracking = true; - break; - case 'k': - out->opts->checkKey = false; - break; - case 'D': - out->opts->forceDecode = true; - break; - case 'r': - out->opts->reverseEncryption = true; - break; - case 'm': - out->opts->mountOnDemand = true; - break; - case 'M': - out->opts->delayMount = true; - break; - case 'N': - useDefaultFlags = false; - break; - case 'o': - PUSHARG("-o"); - PUSHARG( optarg ); - break; - case 'p': - out->opts->passwordProgram.assign( optarg ); - break; - case 'P': - if(geteuid() != 0) - LOG(WARNING) << "option '--public' ignored for non-root user"; - else - { - out->opts->ownerCreate = true; - // add 'allow_other' option - // add 'default_permissions' option (default) + switch (res) { + case '1': + out->opts->configMode = Config_Standard; + break; + case '2': + out->opts->configMode = Config_Paranoia; + break; + case 's': + out->isThreaded = false; + break; + case 'S': + out->opts->useStdin = true; + break; + case 513: + out->opts->annotate = true; + break; + case 'f': + out->isDaemon = false; + // this option was added in fuse 2.x + PUSHARG("-f"); + break; + case 'v': + out->isVerbose = true; + break; + case 'd': + PUSHARG("-d"); + break; + case 'i': + out->idleTimeout = strtol(optarg, (char **)NULL, 10); + out->opts->idleTracking = true; + break; + case 'k': + out->opts->checkKey = false; + break; + case 'D': + out->opts->forceDecode = true; + break; + case 'r': + out->opts->reverseEncryption = true; + break; + case 'm': + out->opts->mountOnDemand = true; + break; + case 'M': + out->opts->delayMount = true; + break; + case 'N': + useDefaultFlags = false; + break; + case 'o': PUSHARG("-o"); - PUSHARG("allow_other"); - } - break; - case 'V': - // xgroup(usage) - cerr << autosprintf(_("encfs version %s"), VERSION) << endl; - exit(EXIT_SUCCESS); - break; - case 'H': - FuseUsage(); - exit(EXIT_SUCCESS); - break; - case '?': - // invalid options.. - break; - case ':': - // missing parameter for option.. - break; - default: - LOG(WARNING) << "getopt error: " << res; - break; + PUSHARG(optarg); + break; + case 'p': + out->opts->passwordProgram.assign(optarg); + break; + case 'P': + if (geteuid() != 0) + LOG(WARNING) << "option '--public' ignored for non-root user"; + else { + out->opts->ownerCreate = true; + // add 'allow_other' option + // add 'default_permissions' option (default) + PUSHARG("-o"); + PUSHARG("allow_other"); + } + break; + case 'V': + // xgroup(usage) + cerr << autosprintf(_("encfs version %s"), VERSION) << endl; + exit(EXIT_SUCCESS); + break; + case 'H': + FuseUsage(); + exit(EXIT_SUCCESS); + break; + case '?': + // invalid options.. + break; + case ':': + // missing parameter for option.. + break; + default: + LOG(WARNING) << "getopt error: " << res; + break; } } - if(!out->isThreaded) - PUSHARG("-s"); + if (!out->isThreaded) PUSHARG("-s"); - if(useDefaultFlags) - { + if (useDefaultFlags) { PUSHARG("-o"); PUSHARG("use_ino"); PUSHARG("-o"); @@ -355,24 +339,20 @@ bool processArgs(int argc, char *argv[], const shared_ptr &out) // we should have at least 2 arguments left over - the source directory and // the mount point. - if(optind+2 <= argc) - { - out->opts->rootDir = slashTerminate( argv[optind++] ); + if (optind + 2 <= argc) { + out->opts->rootDir = slashTerminate(argv[optind++]); out->mountPoint = argv[optind++]; - } else - { + } else { // no mount point specified LOG(ERROR) << "Missing one or more arguments, aborting."; return false; } // If there are still extra unparsed arguments, pass them onto FUSE.. - if(optind < argc) - { + if (optind < argc) { rAssert(out->fuseArgc < MaxFuseArgs); - while(optind < argc) - { + while (optind < argc) { rAssert(out->fuseArgc < MaxFuseArgs); out->fuseArgv[out->fuseArgc++] = argv[optind]; ++optind; @@ -380,65 +360,53 @@ bool processArgs(int argc, char *argv[], const shared_ptr &out) } // sanity check - if(out->isDaemon && - (!isAbsolutePath( out->mountPoint.c_str() ) || - !isAbsolutePath( out->opts->rootDir.c_str() ) ) - ) - { - cerr << - // xgroup(usage) - _("When specifying daemon mode, you must use absolute paths " - "(beginning with '/')") - << endl; + if (out->isDaemon && (!isAbsolutePath(out->mountPoint.c_str()) || + !isAbsolutePath(out->opts->rootDir.c_str()))) { + cerr << + // xgroup(usage) + _("When specifying daemon mode, you must use absolute paths " + "(beginning with '/')") << endl; return false; } // the raw directory may not be a subdirectory of the mount point. { - string testMountPoint = slashTerminate( out->mountPoint ); - string testRootDir = - out->opts->rootDir.substr(0, testMountPoint.length()); + string testMountPoint = slashTerminate(out->mountPoint); + string testRootDir = out->opts->rootDir.substr(0, testMountPoint.length()); - if( testMountPoint == testRootDir ) - { - cerr << - // xgroup(usage) - _("The raw directory may not be a subdirectory of the " + if (testMountPoint == testRootDir) { + cerr << + // xgroup(usage) + _("The raw directory may not be a subdirectory of the " "mount point.") << endl; return false; } } - if(out->opts->delayMount && !out->opts->mountOnDemand) - { + if (out->opts->delayMount && !out->opts->mountOnDemand) { cerr << - // xgroup(usage) - _("You must use mount-on-demand with delay-mount") - << endl; + // xgroup(usage) + _("You must use mount-on-demand with delay-mount") << endl; return false; } - if(out->opts->mountOnDemand && out->opts->passwordProgram.empty()) - { - cerr << - // xgroup(usage) - _("Must set password program when using mount-on-demand") - << endl; + if (out->opts->mountOnDemand && out->opts->passwordProgram.empty()) { + cerr << + // xgroup(usage) + _("Must set password program when using mount-on-demand") << endl; return false; } // check that the directories exist, or that we can create them.. - if(!isDirectory( out->opts->rootDir.c_str() ) && - !userAllowMkdir( out->opts->annotate? 1:0, - out->opts->rootDir.c_str() ,0700)) - { + if (!isDirectory(out->opts->rootDir.c_str()) && + !userAllowMkdir(out->opts->annotate ? 1 : 0, out->opts->rootDir.c_str(), + 0700)) { LOG(WARNING) << "Unable to locate root directory, aborting."; return false; } - if(!isDirectory( out->mountPoint.c_str() ) && - !userAllowMkdir( out->opts->annotate? 2:0, - out->mountPoint.c_str(),0700)) - { + if (!isDirectory(out->mountPoint.c_str()) && + !userAllowMkdir(out->opts->annotate ? 2 : 0, out->mountPoint.c_str(), + 0700)) { LOG(WARNING) << "Unable to locate mount point, aborting."; return false; } @@ -449,99 +417,89 @@ bool processArgs(int argc, char *argv[], const shared_ptr &out) return true; } -static void * idleMonitor(void *); +static void *idleMonitor(void *); -void *encfs_init(fuse_conn_info *conn) -{ - EncFS_Context *ctx = (EncFS_Context*)fuse_get_context()->private_data; +void *encfs_init(fuse_conn_info *conn) { + EncFS_Context *ctx = (EncFS_Context *)fuse_get_context()->private_data; // set fuse connection options conn->async_read = true; // if an idle timeout is specified, then setup a thread to monitor the // filesystem. - if(ctx->args->idleTimeout > 0) - { + if (ctx->args->idleTimeout > 0) { VLOG(1) << "starting idle monitoring thread"; ctx->running = true; - int res = pthread_create( &ctx->monitorThread, 0, idleMonitor, - (void*)ctx ); - if(res != 0) - { + int res = pthread_create(&ctx->monitorThread, 0, idleMonitor, (void *)ctx); + if (res != 0) { LOG(ERROR) << "error starting idle monitor thread, " - "res = " << res << ", errno = " << errno; + "res = " << res << ", errno = " << errno; } } - if(ctx->args->isDaemon && oldStderr >= 0) - { + if (ctx->args->isDaemon && oldStderr >= 0) { VLOG(1) << "Closing stderr"; close(oldStderr); oldStderr = -1; } - return (void*)ctx; + return (void *)ctx; } - -void encfs_destroy( void *_ctx ) -{ - EncFS_Context *ctx = (EncFS_Context*)_ctx; - if(ctx->args->idleTimeout > 0) - { + +void encfs_destroy(void *_ctx) { + EncFS_Context *ctx = (EncFS_Context *)_ctx; + if (ctx->args->idleTimeout > 0) { ctx->running = false; #ifdef CMAKE_USE_PTHREADS_INIT // wake up the thread if it is waiting.. VLOG(1) << "waking up monitoring thread"; ctx->wakeupMutex.lock(); - pthread_cond_signal( &ctx->wakeupCond ); + pthread_cond_signal(&ctx->wakeupCond); ctx->wakeupMutex.unlock(); VLOG(1) << "joining with idle monitoring thread"; - pthread_join( ctx->monitorThread , 0 ); + pthread_join(ctx->monitorThread, 0); VLOG(1) << "join done"; #endif } } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { cerr << "\n\n"; cerr << "====== WARNING ======= WARNING ======== WARNING ========\n"; cerr << "NOTE: this version of Encfs comes from SVN mainline and is\n" - "an unreleased 2.x BETA. It is known to have issues!\n"; + "an unreleased 2.x BETA. It is known to have issues!\n"; cerr << " USE AT YOUR OWN RISK!\n"; cerr << "Stable releases are available from the Encfs website, or look\n" - "for the 1.x branch in SVN for the stable 1.x series."; + "for the 1.x branch in SVN for the stable 1.x series."; cerr << "\n\n"; // log to stderr by default.. - FLAGS_logtostderr = 1; - FLAGS_minloglevel = 1; // WARNING and above. + FLAGS_logtostderr = 1; + FLAGS_minloglevel = 1; // WARNING and above. - google::InitGoogleLogging(argv[0]); + google::InitGoogleLogging(argv[0]); google::InstallFailureSignalHandler(); #ifdef LOCALEDIR - setlocale( LC_ALL, "" ); - bindtextdomain( PACKAGE, LOCALEDIR ); - textdomain( PACKAGE ); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); #endif // anything that comes from the user should be considered tainted until // we've processed it and only allowed through what we support. - shared_ptr encfsArgs( new EncFS_Args ); - for(int i=0; ifuseArgv[i] = NULL; // libfuse expects null args.. + shared_ptr encfsArgs(new EncFS_Args); + for (int i = 0; i < MaxFuseArgs; ++i) + encfsArgs->fuseArgv[i] = NULL; // libfuse expects null args.. - if(argc == 1 || !processArgs(argc, argv, encfsArgs)) - { + if (argc == 1 || !processArgs(argc, argv, encfsArgs)) { usage(argv[0]); return EXIT_FAILURE; } - if(encfsArgs->isVerbose) - FLAGS_minloglevel = 0; + if (encfsArgs->isVerbose) FLAGS_minloglevel = 0; LOG(INFO) << "Root directory: " << encfsArgs->opts->rootDir; LOG(INFO) << "Fuse arguments: " << encfsArgs->toString(); @@ -554,7 +512,7 @@ int main(int argc, char *argv[]) encfs_oper.getattr = encfs_getattr; encfs_oper.readlink = encfs_readlink; - encfs_oper.getdir = encfs_getdir; // deprecated for readdir + encfs_oper.getdir = encfs_getdir; // deprecated for readdir encfs_oper.mknod = encfs_mknod; encfs_oper.mkdir = encfs_mkdir; encfs_oper.unlink = encfs_unlink; @@ -565,7 +523,7 @@ int main(int argc, char *argv[]) encfs_oper.chmod = encfs_chmod; encfs_oper.chown = encfs_chown; encfs_oper.truncate = encfs_truncate; - encfs_oper.utime = encfs_utime; // deprecated for utimens + encfs_oper.utime = encfs_utime; // deprecated for utimens encfs_oper.open = encfs_open; encfs_oper.read = encfs_read; encfs_oper.write = encfs_write; @@ -578,130 +536,122 @@ int main(int argc, char *argv[]) encfs_oper.getxattr = encfs_getxattr; encfs_oper.listxattr = encfs_listxattr; encfs_oper.removexattr = encfs_removexattr; -#endif // HAVE_XATTR - //encfs_oper.opendir = encfs_opendir; - //encfs_oper.readdir = encfs_readdir; - //encfs_oper.releasedir = encfs_releasedir; - //encfs_oper.fsyncdir = encfs_fsyncdir; +#endif // HAVE_XATTR + // encfs_oper.opendir = encfs_opendir; + // encfs_oper.readdir = encfs_readdir; + // encfs_oper.releasedir = encfs_releasedir; + // encfs_oper.fsyncdir = encfs_fsyncdir; encfs_oper.init = encfs_init; encfs_oper.destroy = encfs_destroy; - //encfs_oper.access = encfs_access; - //encfs_oper.create = encfs_create; + // encfs_oper.access = encfs_access; + // encfs_oper.create = encfs_create; encfs_oper.ftruncate = encfs_ftruncate; encfs_oper.fgetattr = encfs_fgetattr; - //encfs_oper.lock = encfs_lock; + // encfs_oper.lock = encfs_lock; encfs_oper.utimens = encfs_utimens; - //encfs_oper.bmap = encfs_bmap; +// encfs_oper.bmap = encfs_bmap; #if (__FreeBSD__ >= 10) - // encfs_oper.setvolname - // encfs_oper.exchange - // encfs_oper.getxtimes - // encfs_oper.setbkuptime - // encfs_oper.setchgtime - // encfs_oper.setcrtime - // encfs_oper.chflags - // encfs_oper.setattr_x - // encfs_oper.fsetattr_x +// encfs_oper.setvolname +// encfs_oper.exchange +// encfs_oper.getxtimes +// encfs_oper.setbkuptime +// encfs_oper.setchgtime +// encfs_oper.setcrtime +// encfs_oper.chflags +// encfs_oper.setattr_x +// encfs_oper.fsetattr_x #endif - CipherV1::init( encfsArgs->isThreaded ); + CipherV1::init(encfsArgs->isThreaded); // context is not a smart pointer because it will live for the life of // the filesystem. EncFS_Context *ctx = new EncFS_Context; ctx->publicFilesystem = encfsArgs->opts->ownerCreate; - RootPtr rootInfo = initFS( ctx, encfsArgs->opts ); + RootPtr rootInfo = initFS(ctx, encfsArgs->opts); int returnCode = EXIT_FAILURE; - if( rootInfo ) - { + if (rootInfo) { // turn off delayMount, as our prior call to initFS has already // respected any delay, and we want future calls to actually mount. encfsArgs->opts->delayMount = false; // set the globally visible root directory node - ctx->setRoot( rootInfo->root ); + ctx->setRoot(rootInfo->root); ctx->args = encfsArgs; ctx->opts = encfsArgs->opts; - if(encfsArgs->isThreaded == false && encfsArgs->idleTimeout > 0) - { + if (encfsArgs->isThreaded == false && encfsArgs->idleTimeout > 0) { // xgroup(usage) cerr << _("Note: requested single-threaded mode, but an idle\n" - "timeout was specified. The filesystem will operate\n" - "single-threaded, but threads will still be used to\n" - "implement idle checking.") << endl; + "timeout was specified. The filesystem will operate\n" + "single-threaded, but threads will still be used to\n" + "implement idle checking.") << endl; } // reset umask now, since we don't want it to interfere with the // pass-thru calls.. - umask( 0 ); + umask(0); - if(encfsArgs->isDaemon) - { + if (encfsArgs->isDaemon) { // switch to logging just warning and error messages via syslog FLAGS_minloglevel = 1; FLAGS_logtostderr = 0; // keep around a pointer just in case we end up needing it to // report a fatal condition later (fuse_main exits unexpectedly)... - oldStderr = dup( STDERR_FILENO ); + oldStderr = dup(STDERR_FILENO); } - try - { + try { time_t startTime, endTime; - if (encfsArgs->opts->annotate) - cerr << "$STATUS$ fuse_main_start" << endl; + if (encfsArgs->opts->annotate) cerr << "$STATUS$ fuse_main_start" << endl; // FIXME: workaround for fuse_main returning an error on normal // exit. Only print information if fuse_main returned // immediately.. - time( &startTime ); + time(&startTime); // fuse_main returns an error code in newer versions of fuse.. - int res = fuse_main( encfsArgs->fuseArgc, - const_cast(encfsArgs->fuseArgv), - &encfs_oper, (void*)ctx); + int res = fuse_main(encfsArgs->fuseArgc, + const_cast(encfsArgs->fuseArgv), &encfs_oper, + (void *)ctx); - time( &endTime ); + time(&endTime); - if (encfsArgs->opts->annotate) - cerr << "$STATUS$ fuse_main_end" << endl; + if (encfsArgs->opts->annotate) cerr << "$STATUS$ fuse_main_end" << endl; - if(res == 0) - returnCode = EXIT_SUCCESS; + if (res == 0) returnCode = EXIT_SUCCESS; - if(res != 0 && encfsArgs->isDaemon && (oldStderr >= 0) - && (endTime - startTime <= 1) ) - { + if (res != 0 && encfsArgs->isDaemon && (oldStderr >= 0) && + (endTime - startTime <= 1)) { // the users will not have seen any message from fuse, so say a // few words in libfuse's memory.. - FILE *out = fdopen( oldStderr, "a" ); + FILE *out = fdopen(oldStderr, "a"); // xgroup(usage) fprintf(out, _("fuse failed. Common problems:\n" - " - fuse kernel module not installed (modprobe fuse)\n" - " - invalid options -- see usage message\n")); + " - fuse kernel module not installed (modprobe fuse)\n" + " - invalid options -- see usage message\n")); fclose(out); } - } catch(std::exception &ex) - { + } + catch (std::exception &ex) { LOG(ERROR) << "Internal error: Caught exception from main loop: " - << ex.what(); - } catch(...) - { + << ex.what(); + } + catch (...) { LOG(ERROR) << "Internal error: Caught unexpected exception"; } } // cleanup so that we can check for leaked resources.. rootInfo.reset(); - ctx->setRoot( shared_ptr() ); + ctx->setRoot(shared_ptr()); - CipherV1::shutdown( encfsArgs->isThreaded ); + CipherV1::shutdown(encfsArgs->isThreaded); return returnCode; } @@ -716,10 +666,8 @@ int main(int argc, char *argv[]) const int ActivityCheckInterval = 10; static bool unmountFS(EncFS_Context *ctx); -static -void * idleMonitor(void *_arg) -{ - EncFS_Context *ctx = (EncFS_Context*)_arg; +static void *idleMonitor(void *_arg) { + EncFS_Context *ctx = (EncFS_Context *)_arg; shared_ptr arg = ctx->args; const int timeoutCycles = 60 * arg->idleTimeout / ActivityCheckInterval; @@ -727,23 +675,20 @@ void * idleMonitor(void *_arg) ctx->wakeupMutex.lock(); - while(ctx->running) - { + while (ctx->running) { int usage = ctx->getAndResetUsageCounter(); - if(usage == 0 && ctx->isMounted()) + if (usage == 0 && ctx->isMounted()) ++idleCycles; else idleCycles = 0; - if(idleCycles >= timeoutCycles) - { + if (idleCycles >= timeoutCycles) { int openCount = ctx->openFileCount(); - if( openCount == 0 && unmountFS( ctx ) ) - { + if (openCount == 0 && unmountFS(ctx)) { #ifdef CMAKE_USE_PTHREADS_INIT // wait for main thread to wake us up - pthread_cond_wait( &ctx->wakeupCond, &ctx->wakeupMutex._mutex ); + pthread_cond_wait(&ctx->wakeupCond, &ctx->wakeupMutex._mutex); #endif break; } @@ -751,17 +696,17 @@ void * idleMonitor(void *_arg) VLOG(1) << "num open files: " << openCount; } - VLOG(1) << "idle cycle count: " << idleCycles - << ", timeout after " << timeoutCycles; + VLOG(1) << "idle cycle count: " << idleCycles << ", timeout after " + << timeoutCycles; struct timeval currentTime; - gettimeofday( ¤tTime, 0 ); + gettimeofday(¤tTime, 0); struct timespec wakeupTime; wakeupTime.tv_sec = currentTime.tv_sec + ActivityCheckInterval; wakeupTime.tv_nsec = currentTime.tv_usec * 1000; #ifdef CMAKE_USE_PTHREADS_INIT - pthread_cond_timedwait( &ctx->wakeupCond, - &ctx->wakeupMutex._mutex, &wakeupTime ); + pthread_cond_timedwait(&ctx->wakeupCond, &ctx->wakeupMutex._mutex, + &wakeupTime); #endif } @@ -772,20 +717,16 @@ void * idleMonitor(void *_arg) return 0; } -static bool unmountFS(EncFS_Context *ctx) -{ +static bool unmountFS(EncFS_Context *ctx) { shared_ptr arg = ctx->args; - LOG(INFO) << "Detaching filesystem " << arg->mountPoint - << " due to inactivity"; + LOG(INFO) << "Detaching filesystem " << arg->mountPoint + << " due to inactivity"; - if( arg->opts->mountOnDemand ) - { - ctx->setRoot( shared_ptr() ); + if (arg->opts->mountOnDemand) { + ctx->setRoot(shared_ptr()); return false; - } else - { - fuse_unmount( arg->mountPoint.c_str() ); + } else { + fuse_unmount(arg->mountPoint.c_str()); return true; } } - diff --git a/fs/BlockFileIO.cpp b/fs/BlockFileIO.cpp index 5dbd178..c4f63ad 100644 --- a/fs/BlockFileIO.cpp +++ b/fs/BlockFileIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -30,131 +30,111 @@ namespace encfs { -template -inline Type min( Type A, Type B ) -{ +template +inline Type min(Type A, Type B) { return (B < A) ? B : A; } -static void clearCache( IORequest &req, int blockSize ) -{ - memset( req.data, 0, blockSize ); +static void clearCache(IORequest &req, int blockSize) { + memset(req.data, 0, blockSize); req.dataLen = 0; } -BlockFileIO::BlockFileIO( int blockSize, const FSConfigPtr &cfg ) - : _blockSize( blockSize ) - , _allowHoles( cfg->config->allow_holes() ) -{ - rAssert( _blockSize > 1 ); - _cache.data = new unsigned char [ _blockSize ]; +BlockFileIO::BlockFileIO(int blockSize, const FSConfigPtr &cfg) + : _blockSize(blockSize), _allowHoles(cfg->config->allow_holes()) { + rAssert(_blockSize > 1); + _cache.data = new unsigned char[_blockSize]; } -BlockFileIO::~BlockFileIO() -{ - clearCache( _cache, _blockSize ); +BlockFileIO::~BlockFileIO() { + clearCache(_cache, _blockSize); delete[] _cache.data; } -ssize_t BlockFileIO::cacheReadOneBlock( const IORequest &req ) const -{ +ssize_t BlockFileIO::cacheReadOneBlock(const IORequest &req) const { // we can satisfy the request even if _cache.dataLen is too short, because // we always request a full block during reads.. - if((req.offset == _cache.offset) && (_cache.dataLen != 0)) - { + if ((req.offset == _cache.offset) && (_cache.dataLen != 0)) { // satisfy request from cache int len = req.dataLen; - if(_cache.dataLen < len) - len = _cache.dataLen; - memcpy( req.data, _cache.data, len ); + if (_cache.dataLen < len) len = _cache.dataLen; + memcpy(req.data, _cache.data, len); return len; - } else - { - if(_cache.dataLen > 0) - clearCache( _cache, _blockSize ); + } else { + if (_cache.dataLen > 0) clearCache(_cache, _blockSize); // cache results of read -- issue reads for full blocks IORequest tmp; tmp.offset = req.offset; tmp.data = _cache.data; tmp.dataLen = _blockSize; - - ssize_t result = readOneBlock( tmp ); - if(result > 0) - { + + ssize_t result = readOneBlock(tmp); + if (result > 0) { _cache.offset = req.offset; - _cache.dataLen = result; // the amount we really have - if(result > req.dataLen) - result = req.dataLen; // only as much as requested - memcpy( req.data, _cache.data, result ); + _cache.dataLen = result; // the amount we really have + if (result > req.dataLen) + result = req.dataLen; // only as much as requested + memcpy(req.data, _cache.data, result); } return result; } } -bool BlockFileIO::cacheWriteOneBlock( const IORequest &req ) -{ +bool BlockFileIO::cacheWriteOneBlock(const IORequest &req) { // cache results of write (before pass-thru, because it may be modified // in-place) - memcpy( _cache.data, req.data, req.dataLen ); + memcpy(_cache.data, req.data, req.dataLen); _cache.offset = req.offset; _cache.dataLen = req.dataLen; - bool ok = writeOneBlock( req ); - if(!ok) - clearCache( _cache, _blockSize ); + bool ok = writeOneBlock(req); + if (!ok) clearCache(_cache, _blockSize); return ok; } -ssize_t BlockFileIO::read( const IORequest &req ) const -{ - rAssert( _blockSize != 0 ); +ssize_t BlockFileIO::read(const IORequest &req) const { + rAssert(_blockSize != 0); int partialOffset = req.offset % _blockSize; off_t blockNum = req.offset / _blockSize; ssize_t result = 0; - if(partialOffset == 0 && req.dataLen <= _blockSize) - { + if (partialOffset == 0 && req.dataLen <= _blockSize) { // read completely within a single block -- can be handled as-is by // readOneBloc(). - return cacheReadOneBlock( req ); - } else - { + return cacheReadOneBlock(req); + } else { size_t size = req.dataLen; // if the request is larger then a block, then request each block // individually - MemBlock mb; // in case we need to allocate a temporary block.. - IORequest blockReq; // for requests we may need to make + MemBlock mb; // in case we need to allocate a temporary block.. + IORequest blockReq; // for requests we may need to make blockReq.dataLen = _blockSize; blockReq.data = NULL; unsigned char *out = req.data; - while( size ) - { + while (size) { blockReq.offset = blockNum * _blockSize; // if we're reading a full block, then read directly into the // result buffer instead of using a temporary - if(partialOffset == 0 && size >= (size_t)_blockSize) + if (partialOffset == 0 && size >= (size_t)_blockSize) blockReq.data = out; - else - { - if(!mb.data) - mb.allocate( _blockSize ); + else { + if (!mb.data) mb.allocate(_blockSize); blockReq.data = mb.data; } - ssize_t readSize = cacheReadOneBlock( blockReq ); - if(readSize <= partialOffset) - break; // didn't get enough bytes + ssize_t readSize = cacheReadOneBlock(blockReq); + if (readSize <= partialOffset) break; // didn't get enough bytes - int cpySize = min( (size_t)(readSize - partialOffset), size ); + int cpySize = min((size_t)(readSize - partialOffset), size); rAssert(cpySize <= readSize); // if we read to a temporary buffer, then move the data - if(blockReq.data != out) - memcpy( out, blockReq.data + partialOffset, cpySize ); + if (blockReq.data != out) + memcpy(out, blockReq.data + partialOffset, cpySize); result += cpySize; size -= cpySize; @@ -162,17 +142,15 @@ ssize_t BlockFileIO::read( const IORequest &req ) const ++blockNum; partialOffset = 0; - if(readSize < _blockSize) - break; + if (readSize < _blockSize) break; } return result; } } -bool BlockFileIO::write( const IORequest &req ) -{ - rAssert( _blockSize != 0 ); +bool BlockFileIO::write(const IORequest &req) { + rAssert(_blockSize != 0); off_t fileSize = getSize(); @@ -185,29 +163,25 @@ bool BlockFileIO::write( const IORequest &req ) ssize_t lastBlockSize = fileSize % _blockSize; off_t lastNonEmptyBlock = lastFileBlock; - if(lastBlockSize == 0) - --lastNonEmptyBlock; + if (lastBlockSize == 0) --lastNonEmptyBlock; - if( req.offset > fileSize ) - { + if (req.offset > fileSize) { // extend file first to fill hole with 0's.. const bool forceWrite = false; - padFile( fileSize, req.offset, forceWrite ); + padFile(fileSize, req.offset, forceWrite); } // check against edge cases where we can just let the base class handle the // request as-is.. - if(partialOffset == 0 && req.dataLen <= _blockSize) - { + if (partialOffset == 0 && req.dataLen <= _blockSize) { // if writing a full block.. pretty safe.. - if( req.dataLen == _blockSize ) - return cacheWriteOneBlock( req ); + if (req.dataLen == _blockSize) return cacheWriteOneBlock(req); // if writing a partial block, but at least as much as what is // already there.. - if(blockNum == lastFileBlock && req.dataLen >= lastBlockSize) - return cacheWriteOneBlock( req ); - } + if (blockNum == lastFileBlock && req.dataLen >= lastBlockSize) + return cacheWriteOneBlock(req); + } // have to merge data with existing block(s).. MemBlock mb; @@ -219,49 +193,42 @@ bool BlockFileIO::write( const IORequest &req ) bool ok = true; size_t size = req.dataLen; unsigned char *inPtr = req.data; - while( size ) - { + while (size) { blockReq.offset = blockNum * _blockSize; int toCopy = min((size_t)(_blockSize - partialOffset), size); // if writing an entire block, or writing a partial block that requires // no merging with existing data.. - if( (toCopy == _blockSize) - ||(partialOffset == 0 && blockReq.offset + toCopy >= fileSize)) - { + if ((toCopy == _blockSize) || + (partialOffset == 0 && blockReq.offset + toCopy >= fileSize)) { // write directly from buffer blockReq.data = inPtr; blockReq.dataLen = toCopy; - } else - { + } else { // need a temporary buffer, since we have to either merge or pad // the data. - if(!mb.data) - mb.allocate( _blockSize ); - memset( mb.data, 0, _blockSize ); + if (!mb.data) mb.allocate(_blockSize); + memset(mb.data, 0, _blockSize); blockReq.data = mb.data; - if(blockNum > lastNonEmptyBlock) - { + if (blockNum > lastNonEmptyBlock) { // just pad.. blockReq.dataLen = toCopy + partialOffset; - } else - { + } else { // have to merge with existing block data.. blockReq.dataLen = _blockSize; - blockReq.dataLen = cacheReadOneBlock( blockReq ); + blockReq.dataLen = cacheReadOneBlock(blockReq); // extend data if necessary.. - if( partialOffset + toCopy > blockReq.dataLen ) + if (partialOffset + toCopy > blockReq.dataLen) blockReq.dataLen = partialOffset + toCopy; } // merge in the data to be written.. - memcpy( blockReq.data + partialOffset, inPtr, toCopy ); + memcpy(blockReq.data + partialOffset, inPtr, toCopy); } // Finally, write the damn thing! - if(!cacheWriteOneBlock( blockReq )) - { + if (!cacheWriteOneBlock(blockReq)) { ok = false; break; } @@ -276,13 +243,9 @@ bool BlockFileIO::write( const IORequest &req ) return ok; } -int BlockFileIO::blockSize() const -{ - return _blockSize; -} +int BlockFileIO::blockSize() const { return _blockSize; } -void BlockFileIO::padFile( off_t oldSize, off_t newSize, bool forceWrite ) -{ +void BlockFileIO::padFile(off_t oldSize, off_t newSize, bool forceWrite) { off_t oldLastBlock = oldSize / _blockSize; off_t newLastBlock = newSize / _blockSize; int lastBlockSize = newSize % _blockSize; @@ -290,78 +253,69 @@ void BlockFileIO::padFile( off_t oldSize, off_t newSize, bool forceWrite ) IORequest req; MemBlock mb; - if(oldLastBlock == newLastBlock) - { + if (oldLastBlock == newLastBlock) { // when the real write occurs, it will have to read in the existing // data and pad it anyway, so we won't do it here (unless we're // forced). - if( forceWrite ) - { - mb.allocate( _blockSize ); + if (forceWrite) { + mb.allocate(_blockSize); req.data = mb.data; req.offset = oldLastBlock * _blockSize; req.dataLen = oldSize % _blockSize; - int outSize = newSize % _blockSize; // outSize > req.dataLen + int outSize = newSize % _blockSize; // outSize > req.dataLen - if(outSize) - { - memset( mb.data, 0, outSize ); - cacheReadOneBlock( req ); + if (outSize) { + memset(mb.data, 0, outSize); + cacheReadOneBlock(req); req.dataLen = outSize; - cacheWriteOneBlock( req ); + cacheWriteOneBlock(req); } } else VLOG(1) << "optimization: not padding last block"; - } else - { - mb.allocate( _blockSize ); + } else { + mb.allocate(_blockSize); req.data = mb.data; // 1. extend the first block to full length // 2. write the middle empty blocks - // 3. write the last block + // 3. write the last block req.offset = oldLastBlock * _blockSize; req.dataLen = oldSize % _blockSize; // 1. req.dataLen == 0, iff oldSize was already a multiple of blocksize - if(req.dataLen != 0) - { + if (req.dataLen != 0) { VLOG(1) << "padding block " << oldLastBlock; - memset( mb.data, 0, _blockSize ); - cacheReadOneBlock( req ); - req.dataLen = _blockSize; // expand to full block size - cacheWriteOneBlock( req ); + memset(mb.data, 0, _blockSize); + cacheReadOneBlock(req); + req.dataLen = _blockSize; // expand to full block size + cacheWriteOneBlock(req); ++oldLastBlock; } // 2, pad zero blocks unless holes are allowed - if(!_allowHoles) - { - for(; oldLastBlock != newLastBlock; ++oldLastBlock) - { + if (!_allowHoles) { + for (; oldLastBlock != newLastBlock; ++oldLastBlock) { VLOG(1) << "padding block " << oldLastBlock; req.offset = oldLastBlock * _blockSize; req.dataLen = _blockSize; - memset( mb.data, 0, req.dataLen ); - cacheWriteOneBlock( req ); + memset(mb.data, 0, req.dataLen); + cacheWriteOneBlock(req); } } // 3. only necessary if write is forced and block is non 0 length - if(forceWrite && lastBlockSize) - { + if (forceWrite && lastBlockSize) { req.offset = newLastBlock * _blockSize; req.dataLen = lastBlockSize; - memset( mb.data, 0, req.dataLen ); - cacheWriteOneBlock( req ); + memset(mb.data, 0, req.dataLen); + cacheWriteOneBlock(req); } } } -int BlockFileIO::blockTruncate( off_t size, FileIO *base ) -{ +int BlockFileIO::blockTruncate(off_t size, FileIO *base) { rAssert(size >= 0); int partialBlock = size % _blockSize; @@ -369,61 +323,51 @@ int BlockFileIO::blockTruncate( off_t size, FileIO *base ) off_t oldSize = getSize(); - if( size > oldSize ) - { + if (size > oldSize) { // truncate can be used to extend a file as well. truncate man page // states that it will pad with 0's. // do the truncate so that the underlying filesystem can allocate // the space, and then we'll fill it in padFile.. - if(base) - base->truncate( size ); + if (base) base->truncate(size); const bool forceWrite = true; - padFile( oldSize, size, forceWrite ); - } else - if( size == oldSize ) - { - // the easiest case, but least likely.... - } else - if( partialBlock ) - { - // partial block after truncate. Need to read in the block being - // truncated before the truncate. Then write it back out afterwards, - // since the encoding will change.. - off_t blockNum = size / _blockSize; - MemBlock mb; - mb.allocate( _blockSize ); + padFile(oldSize, size, forceWrite); + } else if (size == oldSize) { + // the easiest case, but least likely.... + } else if (partialBlock) { + // partial block after truncate. Need to read in the block being + // truncated before the truncate. Then write it back out afterwards, + // since the encoding will change.. + off_t blockNum = size / _blockSize; + MemBlock mb; + mb.allocate(_blockSize); - IORequest req; - req.offset = blockNum * _blockSize; - req.dataLen = _blockSize; - req.data = mb.data; + IORequest req; + req.offset = blockNum * _blockSize; + req.dataLen = _blockSize; + req.data = mb.data; - ssize_t rdSz = cacheReadOneBlock( req ); + ssize_t rdSz = cacheReadOneBlock(req); - // do the truncate - if(base) - res = base->truncate( size ); + // do the truncate + if (base) res = base->truncate(size); - // write back out partial block - req.dataLen = partialBlock; - bool wrRes = cacheWriteOneBlock( req ); + // write back out partial block + req.dataLen = partialBlock; + bool wrRes = cacheWriteOneBlock(req); - if((rdSz < 0) || (!wrRes)) - { - LOG(ERROR) << "truncate failure: read size " << rdSz - << ", partial block of " << partialBlock; - } + if ((rdSz < 0) || (!wrRes)) { + LOG(ERROR) << "truncate failure: read size " << rdSz + << ", partial block of " << partialBlock; + } - } else - { - // truncating on a block bounday. No need to re-encode the last - // block.. - if(base) - res = base->truncate( size ); - } + } else { + // truncating on a block bounday. No need to re-encode the last + // block.. + if (base) res = base->truncate(size); + } - return res; + return res; } } // namespace encfs diff --git a/fs/BlockFileIO.h b/fs/BlockFileIO.h index 4cc8898..7adf3f6 100644 --- a/fs/BlockFileIO.h +++ b/fs/BlockFileIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -28,45 +28,42 @@ namespace encfs { /* Implements block scatter / gather interface. Requires derived classes to - implement readOneBlock() / writeOneBlock() at a minimum. + implement readOneBlock() / writeOneBlock() at a minimum. When a partial block write is requested it will be turned into a read of the existing block, merge with the write request, and a write of the full block. */ -class BlockFileIO : public FileIO -{ -public: - BlockFileIO( int blockSize, const FSConfigPtr &cfg ); - virtual ~BlockFileIO(); +class BlockFileIO : public FileIO { + public: + BlockFileIO(int blockSize, const FSConfigPtr &cfg); + virtual ~BlockFileIO(); - // implemented in terms of blocks. - virtual ssize_t read( const IORequest &req ) const; - virtual bool write( const IORequest &req ); + // implemented in terms of blocks. + virtual ssize_t read(const IORequest &req) const; + virtual bool write(const IORequest &req); - virtual int blockSize() const; + virtual int blockSize() const; -protected: + protected: + int blockTruncate(off_t size, FileIO *base); + void padFile(off_t oldSize, off_t newSize, bool forceWrite); - int blockTruncate( off_t size, FileIO *base ); - void padFile( off_t oldSize, off_t newSize, bool forceWrite ); + // same as read(), except that the request.offset field is guarenteed to be + // block aligned, and the request size will not be larger then 1 block. + virtual ssize_t readOneBlock(const IORequest &req) const = 0; + virtual bool writeOneBlock(const IORequest &req) = 0; - // same as read(), except that the request.offset field is guarenteed to be - // block aligned, and the request size will not be larger then 1 block. - virtual ssize_t readOneBlock( const IORequest &req ) const =0; - virtual bool writeOneBlock( const IORequest &req ) =0; - - ssize_t cacheReadOneBlock( const IORequest &req ) const; - bool cacheWriteOneBlock( const IORequest &req ); + ssize_t cacheReadOneBlock(const IORequest &req) const; + bool cacheWriteOneBlock(const IORequest &req); - int _blockSize; - bool _allowHoles; + int _blockSize; + bool _allowHoles; - // cache last block for speed... - mutable IORequest _cache; + // cache last block for speed... + mutable IORequest _cache; }; } // namespace encfs #endif - diff --git a/fs/BlockNameIO.cpp b/fs/BlockNameIO.cpp index 293e76f..25248a3 100644 --- a/fs/BlockNameIO.cpp +++ b/fs/BlockNameIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -30,33 +30,30 @@ namespace encfs { -static shared_ptr NewBlockNameIO( const Interface &iface, - const shared_ptr &cipher ) -{ - return shared_ptr( - new BlockNameIO( iface, cipher, false)); +static shared_ptr NewBlockNameIO(const Interface &iface, + const shared_ptr &cipher) { + return shared_ptr(new BlockNameIO(iface, cipher, false)); } -static shared_ptr NewBlockNameIO32( const Interface &iface, - const shared_ptr &cipher ) -{ - return shared_ptr( - new BlockNameIO( iface, cipher, true)); +static shared_ptr NewBlockNameIO32(const Interface &iface, + const shared_ptr &cipher) { + return shared_ptr(new BlockNameIO(iface, cipher, true)); } -static bool BlockIO_registered = NameIO::Register("Block", +static bool BlockIO_registered = NameIO::Register( + "Block", // description of block name encoding algorithm.. // xgroup(setup) gettext_noop("Block encoding, hides file name size somewhat"), - BlockNameIO::CurrentInterface(false), - NewBlockNameIO, false); + BlockNameIO::CurrentInterface(false), NewBlockNameIO, false); -static bool BlockIO32_registered = NameIO::Register("Block32", +static bool BlockIO32_registered = NameIO::Register( + "Block32", // description of block name encoding algorithm.. // xgroup(setup) - gettext_noop("Block encoding with base32 output for case-sensitive systems"), - BlockNameIO::CurrentInterface(true), - NewBlockNameIO32, false); + gettext_noop( + "Block encoding with base32 output for case-sensitive systems"), + BlockNameIO::CurrentInterface(true), NewBlockNameIO32, false); /* - Version 1.0 computed MAC over the filename, but not the padding bytes. @@ -75,8 +72,7 @@ static bool BlockIO32_registered = NameIO::Register("Block32", - Version 4.0 adds support for base32, creating names more suitable for case-insensitive filesystems (eg Mac). */ -Interface BlockNameIO::CurrentInterface(bool caseSensitive) -{ +Interface BlockNameIO::CurrentInterface(bool caseSensitive) { // implement major version 4 plus support for two prior versions if (caseSensitive) return makeInterface("nameio/block32", 4, 0, 2); @@ -84,172 +80,146 @@ Interface BlockNameIO::CurrentInterface(bool caseSensitive) return makeInterface("nameio/block", 4, 0, 2); } -BlockNameIO::BlockNameIO( const Interface &iface, - const shared_ptr &cipher, - bool caseSensitiveEncoding ) - : _interface( iface.major() ) - , _bs( cipher->cipherBlockSize() ) - , _cipher( cipher ) - , _caseSensitive( caseSensitiveEncoding ) -{ - rAssert( _bs < 128 ); +BlockNameIO::BlockNameIO(const Interface &iface, + const shared_ptr &cipher, + bool caseSensitiveEncoding) + : _interface(iface.major()), + _bs(cipher->cipherBlockSize()), + _cipher(cipher), + _caseSensitive(caseSensitiveEncoding) { + rAssert(_bs < 128); } -BlockNameIO::~BlockNameIO() -{ -} +BlockNameIO::~BlockNameIO() {} -Interface BlockNameIO::interface() const -{ +Interface BlockNameIO::interface() const { return CurrentInterface(_caseSensitive); } -int BlockNameIO::maxEncodedNameLen( int plaintextNameLen ) const -{ +int BlockNameIO::maxEncodedNameLen(int plaintextNameLen) const { // number of blocks, rounded up.. Only an estimate at this point, err on // the size of too much space rather then too little. - int numBlocks = ( plaintextNameLen + _bs ) / _bs; - int encodedNameLen = numBlocks * _bs + 2; // 2 checksum bytes + int numBlocks = (plaintextNameLen + _bs) / _bs; + int encodedNameLen = numBlocks * _bs + 2; // 2 checksum bytes if (_caseSensitive) - return B256ToB32Bytes( encodedNameLen ); + return B256ToB32Bytes(encodedNameLen); else - return B256ToB64Bytes( encodedNameLen ); + return B256ToB64Bytes(encodedNameLen); } -int BlockNameIO::maxDecodedNameLen( int encodedNameLen ) const -{ - int decLen256 = _caseSensitive ? - B32ToB256Bytes( encodedNameLen ) : - B64ToB256Bytes( encodedNameLen ); - return decLen256 - 2; // 2 checksum bytes removed.. +int BlockNameIO::maxDecodedNameLen(int encodedNameLen) const { + int decLen256 = _caseSensitive ? B32ToB256Bytes(encodedNameLen) + : B64ToB256Bytes(encodedNameLen); + return decLen256 - 2; // 2 checksum bytes removed.. } -int BlockNameIO::encodeName( const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const -{ +int BlockNameIO::encodeName(const char *plaintextName, int length, uint64_t *iv, + char *encodedName) const { // copy the data into the encoding buffer.. - memcpy( encodedName+2, plaintextName, length ); + memcpy(encodedName + 2, plaintextName, length); // Pad encryption buffer to block boundary.. int padding = _bs - length % _bs; - if(padding == 0) - padding = _bs; // padding a full extra block! + if (padding == 0) padding = _bs; // padding a full extra block! - memset( encodedName+length+2, (unsigned char)padding, padding ); + memset(encodedName + length + 2, (unsigned char)padding, padding); // store the IV before it is modified by the MAC call. uint64_t tmpIV = 0; - if( iv && _interface >= 3 ) - tmpIV = *iv; + if (iv && _interface >= 3) tmpIV = *iv; // include padding in MAC computation unsigned int mac = _cipher->reduceMac16( - _cipher->MAC_64( (unsigned char *)encodedName+2, - length+padding, iv )); + _cipher->MAC_64((unsigned char *)encodedName + 2, length + padding, iv)); // add checksum bytes encodedName[0] = (mac >> 8) & 0xff; - encodedName[1] = (mac ) & 0xff; + encodedName[1] = (mac) & 0xff; - _cipher->blockEncode( (unsigned char *)encodedName+2, length+padding, - (uint64_t)mac ^ tmpIV ); + _cipher->blockEncode((unsigned char *)encodedName + 2, length + padding, + (uint64_t)mac ^ tmpIV); // convert to base 64 ascii int encodedStreamLen = length + 2 + padding; int encLen; - if (_caseSensitive) - { - encLen = B256ToB32Bytes( encodedStreamLen ); + if (_caseSensitive) { + encLen = B256ToB32Bytes(encodedStreamLen); - changeBase2Inline( (unsigned char *)encodedName, encodedStreamLen, - 8, 5, true ); - B32ToAscii( (unsigned char *)encodedName, encLen ); - } else - { - encLen = B256ToB64Bytes( encodedStreamLen ); + changeBase2Inline((unsigned char *)encodedName, encodedStreamLen, 8, 5, + true); + B32ToAscii((unsigned char *)encodedName, encLen); + } else { + encLen = B256ToB64Bytes(encodedStreamLen); - changeBase2Inline( (unsigned char *)encodedName, encodedStreamLen, - 8, 6, true ); - B64ToAscii( (unsigned char *)encodedName, encLen ); + changeBase2Inline((unsigned char *)encodedName, encodedStreamLen, 8, 6, + true); + B64ToAscii((unsigned char *)encodedName, encLen); } return encLen; } -int BlockNameIO::decodeName( const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const -{ - int decLen256 = _caseSensitive ? - B32ToB256Bytes( length ) : - B64ToB256Bytes( length ); +int BlockNameIO::decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const { + int decLen256 = + _caseSensitive ? B32ToB256Bytes(length) : B64ToB256Bytes(length); int decodedStreamLen = decLen256 - 2; // don't bother trying to decode files which are too small - if(decodedStreamLen < _bs) - throw Error("Filename too small to decode"); + if (decodedStreamLen < _bs) throw Error("Filename too small to decode"); - BUFFER_INIT( tmpBuf, 32, (unsigned int)length ); + BUFFER_INIT(tmpBuf, 32, (unsigned int)length); // decode into tmpBuf, - if (_caseSensitive) - { + if (_caseSensitive) { AsciiToB32((unsigned char *)tmpBuf, (unsigned char *)encodedName, length); changeBase2Inline((unsigned char *)tmpBuf, length, 5, 8, false); - } else - { + } else { AsciiToB64((unsigned char *)tmpBuf, (unsigned char *)encodedName, length); changeBase2Inline((unsigned char *)tmpBuf, length, 6, 8, false); } // pull out the header information - unsigned int mac = ((unsigned int)((unsigned char)tmpBuf[0])) << 8 - | ((unsigned int)((unsigned char)tmpBuf[1])); + unsigned int mac = ((unsigned int)((unsigned char)tmpBuf[0])) << 8 | + ((unsigned int)((unsigned char)tmpBuf[1])); uint64_t tmpIV = 0; - if( iv && _interface >= 3 ) - tmpIV = *iv; + if (iv && _interface >= 3) tmpIV = *iv; - _cipher->blockDecode( (unsigned char *)tmpBuf+2, decodedStreamLen, - (uint64_t)mac ^ tmpIV ); + _cipher->blockDecode((unsigned char *)tmpBuf + 2, decodedStreamLen, + (uint64_t)mac ^ tmpIV); // find out true string length - int padding = (unsigned char)tmpBuf[2+decodedStreamLen-1]; + int padding = (unsigned char)tmpBuf[2 + decodedStreamLen - 1]; int finalSize = decodedStreamLen - padding; // might happen if there is an error decoding.. - if(padding > _bs || finalSize < 0) - { - VLOG(1) << "padding, _bx, finalSize = " << padding - << ", " << _bs << ", " << finalSize; - throw Error( "invalid padding size" ); + if (padding > _bs || finalSize < 0) { + VLOG(1) << "padding, _bx, finalSize = " << padding << ", " << _bs << ", " + << finalSize; + throw Error("invalid padding size"); } // copy out the result.. - memcpy(plaintextName, tmpBuf+2, finalSize); + memcpy(plaintextName, tmpBuf + 2, finalSize); plaintextName[finalSize] = '\0'; // check the mac unsigned int mac2 = _cipher->reduceMac16( - _cipher->MAC_64((const unsigned char *)tmpBuf+2, - decodedStreamLen, iv)); + _cipher->MAC_64((const unsigned char *)tmpBuf + 2, decodedStreamLen, iv)); - BUFFER_RESET( tmpBuf ); + BUFFER_RESET(tmpBuf); - if(mac2 != mac) - { - LOG(INFO) << "checksum mismatch: expected " << mac << ", got " - << mac2 << " on decode of " << finalSize << " bytes"; - throw Error( "checksum mismatch in filename decode" ); + if (mac2 != mac) { + LOG(INFO) << "checksum mismatch: expected " << mac << ", got " << mac2 + << " on decode of " << finalSize << " bytes"; + throw Error("checksum mismatch in filename decode"); } return finalSize; } -bool BlockNameIO::Enabled() -{ - return true; -} +bool BlockNameIO::Enabled() { return true; } } // namespace encfs - diff --git a/fs/BlockNameIO.h b/fs/BlockNameIO.h index bd19791..9fb61d7 100644 --- a/fs/BlockNameIO.h +++ b/fs/BlockNameIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -34,28 +34,27 @@ class CipherV1; mode to encode filenames. The filenames are padded to be a multiple of the cipher block size. */ -class BlockNameIO : public NameIO -{ +class BlockNameIO : public NameIO { public: static Interface CurrentInterface(bool caseSensitive = false); - BlockNameIO(const Interface &iface, - const shared_ptr &cipher, - bool caseSensitiveEncoding = false ); + BlockNameIO(const Interface &iface, const shared_ptr &cipher, + bool caseSensitiveEncoding = false); virtual ~BlockNameIO(); virtual Interface interface() const; - virtual int maxEncodedNameLen( int plaintextNameLen ) const; - virtual int maxDecodedNameLen( int encodedNameLen ) const; + virtual int maxEncodedNameLen(int plaintextNameLen) const; + virtual int maxDecodedNameLen(int encodedNameLen) const; // hack to help with static builds static bool Enabled(); + protected: - virtual int encodeName(const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const; - virtual int decodeName(const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const; + virtual int encodeName(const char *plaintextName, int length, uint64_t *iv, + char *encodedName) const; + virtual int decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const; private: int _interface; @@ -67,4 +66,3 @@ class BlockNameIO : public NameIO } // namespace encfs #endif - diff --git a/fs/CipherFileIO.cpp b/fs/CipherFileIO.cpp index 2bb4438..f567c98 100644 --- a/fs/CipherFileIO.cpp +++ b/fs/CipherFileIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -40,90 +40,68 @@ namespace encfs { */ static Interface CipherFileIO_iface = makeInterface("FileIO/Cipher", 3, 0, 2); -CipherFileIO::CipherFileIO( const shared_ptr &_base, - const FSConfigPtr &cfg) - : BlockFileIO( cfg->config->block_size(), cfg ) - , base( _base ) - , headerLen( 0 ) - , perFileIV( cfg->config->unique_iv() ) - , externalIV( 0 ) - , fileIV( 0 ) - , lastFlags( 0 ) -{ +CipherFileIO::CipherFileIO(const shared_ptr &_base, + const FSConfigPtr &cfg) + : BlockFileIO(cfg->config->block_size(), cfg), + base(_base), + headerLen(0), + perFileIV(cfg->config->unique_iv()), + externalIV(0), + fileIV(0), + lastFlags(0) { fsConfig = cfg; cipher = cfg->cipher; - if ( perFileIV ) - headerLen += sizeof(uint64_t); // 64bit IV per file + if (perFileIV) headerLen += sizeof(uint64_t); // 64bit IV per file - int blockBoundary = fsConfig->config->block_size() % - fsConfig->cipher->cipherBlockSize(); - if(blockBoundary != 0) - { - LOG_FIRST_N(ERROR, 1) - << "CipherFileIO: blocks should be multiple of cipher block size"; + int blockBoundary = + fsConfig->config->block_size() % fsConfig->cipher->cipherBlockSize(); + if (blockBoundary != 0) { + LOG_FIRST_N(ERROR, 1) + << "CipherFileIO: blocks should be multiple of cipher block size"; } } -CipherFileIO::~CipherFileIO() -{ -} +CipherFileIO::~CipherFileIO() {} -Interface CipherFileIO::interface() const -{ - return CipherFileIO_iface; -} +Interface CipherFileIO::interface() const { return CipherFileIO_iface; } -int CipherFileIO::open( int flags ) -{ - int res = base->open( flags ); - - if( res >= 0 ) - lastFlags = flags; +int CipherFileIO::open(int flags) { + int res = base->open(flags); + + if (res >= 0) lastFlags = flags; return res; } -void CipherFileIO::setFileName( const char *fileName ) -{ - base->setFileName( fileName ); +void CipherFileIO::setFileName(const char *fileName) { + base->setFileName(fileName); } -const char *CipherFileIO::getFileName() const -{ - return base->getFileName(); -} +const char *CipherFileIO::getFileName() const { return base->getFileName(); } -bool CipherFileIO::setIV( uint64_t iv ) -{ - VLOG(1) << "in setIV, current IV = " << externalIV - << ", new IV = " << iv << ", fileIV = " << fileIV; - if(externalIV == 0) - { +bool CipherFileIO::setIV(uint64_t iv) { + VLOG(1) << "in setIV, current IV = " << externalIV << ", new IV = " << iv + << ", fileIV = " << fileIV; + if (externalIV == 0) { // we're just being told about which IV to use. since we haven't // initialized the fileIV, there is no need to just yet.. externalIV = iv; - LOG_IF(WARNING, fileIV != 0) - << "fileIV initialized before externalIV! (" << fileIV - << ", " << externalIV << ")"; - } else if(perFileIV) - { + LOG_IF(WARNING, fileIV != 0) << "fileIV initialized before externalIV! (" + << fileIV << ", " << externalIV << ")"; + } else if (perFileIV) { // we have an old IV, and now a new IV, so we need to update the fileIV // on disk. - if(fileIV == 0) - { + if (fileIV == 0) { // ensure the file is open for read/write.. int newFlags = lastFlags | O_RDWR; - int res = base->open( newFlags ); - if(res < 0) - { - if(res == -EISDIR) - { + int res = base->open(newFlags); + if (res < 0) { + if (res == -EISDIR) { // duh -- there are no file headers for directories! externalIV = iv; - return base->setIV( iv ); - } else - { + return base->setIV(iv); + } else { VLOG(1) << "writeHeader failed to re-open for write"; return false; } @@ -133,46 +111,40 @@ bool CipherFileIO::setIV( uint64_t iv ) uint64_t oldIV = externalIV; externalIV = iv; - if(!writeHeader()) - { + if (!writeHeader()) { externalIV = oldIV; return false; } } - return base->setIV( iv ); + return base->setIV(iv); } -off_t CipherFileIO::adjustedSize(off_t rawSize) const -{ +off_t CipherFileIO::adjustedSize(off_t rawSize) const { off_t size = rawSize; - if (rawSize >= headerLen) - size -= headerLen; + if (rawSize >= headerLen) size -= headerLen; return size; } -int CipherFileIO::getAttr( struct stat *stbuf ) const -{ - int res = base->getAttr( stbuf ); +int CipherFileIO::getAttr(struct stat *stbuf) const { + int res = base->getAttr(stbuf); // adjust size if we have a file header - if((res == 0) && S_ISREG(stbuf->st_mode)) + if ((res == 0) && S_ISREG(stbuf->st_mode)) stbuf->st_size = adjustedSize(stbuf->st_size); return res; } -off_t CipherFileIO::getSize() const -{ +off_t CipherFileIO::getSize() const { // No check on S_ISREG here -- getSize only for normal files! off_t size = base->getSize(); return adjustedSize(size); } -void CipherFileIO::initHeader( ) -{ +void CipherFileIO::initHeader() { int cbs = cipher->cipherBlockSize(); MemBlock mb; @@ -181,90 +153,79 @@ void CipherFileIO::initHeader( ) // check if the file has a header, and read it if it does.. Otherwise, // create one. off_t rawSize = base->getSize(); - if(rawSize >= headerLen) - { + if (rawSize >= headerLen) { VLOG(1) << "reading existing header, rawSize = " << rawSize; IORequest req; req.offset = 0; req.data = mb.data; req.dataLen = sizeof(uint64_t); - base->read( req ); + base->read(req); - if (perFileIV) - { - cipher->streamDecode( mb.data, sizeof(uint64_t), externalIV ); + if (perFileIV) { + cipher->streamDecode(mb.data, sizeof(uint64_t), externalIV); fileIV = 0; - for(unsigned int i=0; ipseudoRandomize( mb.data, 8 )) + do { + if (!cipher->pseudoRandomize(mb.data, 8)) throw Error("Unable to generate a random file IV"); fileIV = 0; - for(unsigned int i=0; istreamEncode( mb.data, sizeof(uint64_t), externalIV ); + << "Unexpected result: randomize returned 8 null bytes!"; + } while (fileIV == 0); // don't accept 0 as an option.. - if( base->isWritable() ) - { + cipher->streamEncode(mb.data, sizeof(uint64_t), externalIV); + + if (base->isWritable()) { IORequest req; req.offset = 0; req.data = mb.data; req.dataLen = sizeof(uint64_t); - base->write( req ); + base->write(req); } else VLOG(1) << "base not writable, IV not written.."; } VLOG(1) << "initHeader finished, fileIV = " << fileIV; } -bool CipherFileIO::writeHeader( ) -{ - if( !base->isWritable() ) - { +bool CipherFileIO::writeHeader() { + if (!base->isWritable()) { // open for write.. int newFlags = lastFlags | O_RDWR; - if( base->open( newFlags ) < 0 ) - { + if (base->open(newFlags) < 0) { VLOG(1) << "writeHeader failed to re-open for write"; return false; } - } + } - LOG_IF(ERROR, fileIV == 0) - << "Internal error: fileIV == 0 in writeHeader!!!"; + LOG_IF(ERROR, fileIV == 0) << "Internal error: fileIV == 0 in writeHeader!!!"; VLOG(1) << "writing fileIV " << fileIV; MemBlock mb; mb.allocate(headerLen); - if (perFileIV) - { + if (perFileIV) { unsigned char *buf = mb.data; - for(int i=sizeof(buf)-1; i>=0; --i) - { + for (int i = sizeof(buf) - 1; i >= 0; --i) { buf[i] = (unsigned char)(fileIV & 0xff); fileIV >>= 8; } - cipher->streamEncode( buf, sizeof(uint64_t), externalIV ); + cipher->streamEncode(buf, sizeof(uint64_t), externalIV); } IORequest req; @@ -272,13 +233,12 @@ bool CipherFileIO::writeHeader( ) req.data = mb.data; req.dataLen = headerLen; - base->write( req ); + base->write(req); return true; } -ssize_t CipherFileIO::readOneBlock( const IORequest &req ) const -{ +ssize_t CipherFileIO::readOneBlock(const IORequest &req) const { // read raw data, then decipher it.. int bs = blockSize(); rAssert(req.dataLen <= bs); @@ -292,31 +252,25 @@ ssize_t CipherFileIO::readOneBlock( const IORequest &req ) const tmpReq.offset += headerLen; int maxReadSize = req.dataLen; - readSize = base->read( tmpReq ); + readSize = base->read(tmpReq); bool ok; - if(readSize > 0) - { - if(headerLen != 0 && fileIV == 0) - const_cast(this)->initHeader(); + if (readSize > 0) { + if (headerLen != 0 && fileIV == 0) + const_cast(this)->initHeader(); - if(readSize == bs) - { - ok = blockRead( tmpReq.data, bs, blockNum ^ fileIV); - } else - { - ok = streamRead( tmpReq.data, (int)readSize, blockNum ^ fileIV); + if (readSize == bs) { + ok = blockRead(tmpReq.data, bs, blockNum ^ fileIV); + } else { + ok = streamRead(tmpReq.data, (int)readSize, blockNum ^ fileIV); } - if(!ok) - { - VLOG(1) << "decodeBlock failed for block " << blockNum - << ", size " << readSize; + if (!ok) { + VLOG(1) << "decodeBlock failed for block " << blockNum << ", size " + << readSize; readSize = -1; - } else if (tmpReq.data != req.data) - { - if (readSize > maxReadSize) - readSize = maxReadSize; + } else if (tmpReq.data != req.data) { + if (readSize > maxReadSize) readSize = maxReadSize; memcpy(req.data, tmpReq.data, readSize); } } else @@ -325,38 +279,28 @@ ssize_t CipherFileIO::readOneBlock( const IORequest &req ) const return readSize; } - -bool CipherFileIO::writeOneBlock( const IORequest &req ) -{ +bool CipherFileIO::writeOneBlock(const IORequest &req) { int bs = blockSize(); off_t blockNum = req.offset / bs; - if(headerLen != 0 && fileIV == 0) - initHeader(); + if (headerLen != 0 && fileIV == 0) initHeader(); MemBlock mb; bool ok; - if (req.dataLen == bs) - { - ok = blockWrite( req.data, bs, blockNum ^ fileIV ); - } else - { - ok = streamWrite( req.data, (int)req.dataLen, - blockNum ^ fileIV ); + if (req.dataLen == bs) { + ok = blockWrite(req.data, bs, blockNum ^ fileIV); + } else { + ok = streamWrite(req.data, (int)req.dataLen, blockNum ^ fileIV); } - if( ok ) - { - if(headerLen != 0) - { + if (ok) { + if (headerLen != 0) { IORequest nreq = req; - if (mb.data == NULL) - { + if (mb.data == NULL) { nreq.offset += headerLen; - } else - { + } else { // Partial block is stored at front of file. nreq.offset = 0; nreq.data = mb.data; @@ -364,78 +308,66 @@ bool CipherFileIO::writeOneBlock( const IORequest &req ) base->truncate(req.offset + req.dataLen + headerLen); } - ok = base->write( nreq ); + ok = base->write(nreq); } else - ok = base->write( req ); - } else - { - VLOG(1) << "encodeBlock failed for block " << blockNum - << ", size " << req.dataLen; + ok = base->write(req); + } else { + VLOG(1) << "encodeBlock failed for block " << blockNum << ", size " + << req.dataLen; ok = false; } return ok; } -bool CipherFileIO::blockWrite( unsigned char *buf, int size, - uint64_t _iv64 ) const -{ +bool CipherFileIO::blockWrite(unsigned char *buf, int size, + uint64_t _iv64) const { if (!fsConfig->reverseEncryption) - return cipher->blockEncode( buf, size, _iv64 ); + return cipher->blockEncode(buf, size, _iv64); else - return cipher->blockDecode( buf, size, _iv64 ); -} + return cipher->blockDecode(buf, size, _iv64); +} -bool CipherFileIO::streamWrite( unsigned char *buf, int size, - uint64_t _iv64 ) const -{ +bool CipherFileIO::streamWrite(unsigned char *buf, int size, + uint64_t _iv64) const { if (!fsConfig->reverseEncryption) - return cipher->streamEncode( buf, size, _iv64 ); + return cipher->streamEncode(buf, size, _iv64); else - return cipher->streamDecode( buf, size, _iv64 ); -} + return cipher->streamDecode(buf, size, _iv64); +} - -bool CipherFileIO::blockRead( unsigned char *buf, int size, - uint64_t _iv64 ) const -{ +bool CipherFileIO::blockRead(unsigned char *buf, int size, + uint64_t _iv64) const { if (fsConfig->reverseEncryption) - return cipher->blockEncode( buf, size, _iv64 ); - else if(_allowHoles) - { + return cipher->blockEncode(buf, size, _iv64); + else if (_allowHoles) { // special case - leave all 0's alone - for(int i=0; iblockDecode( buf, size, _iv64 ); + for (int i = 0; i < size; ++i) + if (buf[i] != 0) return cipher->blockDecode(buf, size, _iv64); return true; } else - return cipher->blockDecode( buf, size, _iv64 ); -} + return cipher->blockDecode(buf, size, _iv64); +} -bool CipherFileIO::streamRead( unsigned char *buf, int size, - uint64_t _iv64 ) const -{ +bool CipherFileIO::streamRead(unsigned char *buf, int size, + uint64_t _iv64) const { if (fsConfig->reverseEncryption) - return cipher->streamEncode( buf, size, _iv64 ); + return cipher->streamEncode(buf, size, _iv64); else - return cipher->streamDecode( buf, size, _iv64 ); -} + return cipher->streamDecode(buf, size, _iv64); +} -int CipherFileIO::truncate( off_t size ) -{ +int CipherFileIO::truncate(off_t size) { rAssert(size >= 0); - if(headerLen == 0) - { - return blockTruncate( size, base.get() ); - } else if(0 == fileIV) - { + if (headerLen == 0) { + return blockTruncate(size, base.get()); + } else if (0 == fileIV) { // empty file.. create the header.. - if( !base->isWritable() ) - { + if (!base->isWritable()) { // open for write.. int newFlags = lastFlags | O_RDWR; - if( base->open( newFlags ) < 0 ) + if (base->open(newFlags) < 0) VLOG(1) << "writeHeader failed to re-open for write"; } initHeader(); @@ -443,17 +375,13 @@ int CipherFileIO::truncate( off_t size ) // can't let BlockFileIO call base->truncate(), since it would be using // the wrong size.. - int res = blockTruncate( size, 0 ); + int res = blockTruncate(size, 0); - if(res == 0) - base->truncate( size + headerLen ); + if (res == 0) base->truncate(size + headerLen); return res; } -bool CipherFileIO::isWritable() const -{ - return base->isWritable(); -} +bool CipherFileIO::isWritable() const { return base->isWritable(); } } // namespace encfs diff --git a/fs/CipherFileIO.h b/fs/CipherFileIO.h index 2c17f5b..f3f3bfa 100644 --- a/fs/CipherFileIO.h +++ b/fs/CipherFileIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -32,66 +32,60 @@ namespace encfs { class CipherV1; /* - Implement the FileIO interface encrypting data in blocks. - + Implement the FileIO interface encrypting data in blocks. + Uses BlockFileIO to handle the block scatter / gather issues. */ -class CipherFileIO : public BlockFileIO -{ -public: - CipherFileIO( const shared_ptr &base, - const FSConfigPtr &cfg); - virtual ~CipherFileIO(); +class CipherFileIO : public BlockFileIO { + public: + CipherFileIO(const shared_ptr &base, const FSConfigPtr &cfg); + virtual ~CipherFileIO(); - virtual Interface interface() const; + virtual Interface interface() const; - virtual void setFileName( const char *fileName ); - virtual const char *getFileName() const; - virtual bool setIV( uint64_t iv ); + virtual void setFileName(const char *fileName); + virtual const char *getFileName() const; + virtual bool setIV(uint64_t iv); - virtual int open( int flags ); + virtual int open(int flags); - virtual int getAttr( struct stat *stbuf ) const; - virtual off_t getSize() const; + virtual int getAttr(struct stat *stbuf) const; + virtual off_t getSize() const; - // NOTE: if truncate is used to extend the file, the extended plaintext is - // not 0. The extended ciphertext may be 0, resulting in non-zero - // plaintext. - virtual int truncate( off_t size ); + // NOTE: if truncate is used to extend the file, the extended plaintext is + // not 0. The extended ciphertext may be 0, resulting in non-zero + // plaintext. + virtual int truncate(off_t size); - virtual bool isWritable() const; + virtual bool isWritable() const; -private: - virtual ssize_t readOneBlock( const IORequest &req ) const; - virtual bool writeOneBlock( const IORequest &req ); + private: + virtual ssize_t readOneBlock(const IORequest &req) const; + virtual bool writeOneBlock(const IORequest &req); - void initHeader(); - bool writeHeader(); - bool blockRead( unsigned char *buf, int size, - uint64_t iv64 ) const; - bool streamRead( unsigned char *buf, int size, - uint64_t iv64 ) const; - bool blockWrite( unsigned char *buf, int size, - uint64_t iv64 ) const; - bool streamWrite( unsigned char *buf, int size, - uint64_t iv64 ) const; + void initHeader(); + bool writeHeader(); + bool blockRead(unsigned char *buf, int size, uint64_t iv64) const; + bool streamRead(unsigned char *buf, int size, uint64_t iv64) const; + bool blockWrite(unsigned char *buf, int size, uint64_t iv64) const; + bool streamWrite(unsigned char *buf, int size, uint64_t iv64) const; - off_t adjustedSize(off_t size) const; + off_t adjustedSize(off_t size) const; - shared_ptr base; + shared_ptr base; - FSConfigPtr fsConfig; + FSConfigPtr fsConfig; - // if haveHeader is true, then we have a transparent file header which - int headerLen; + // if haveHeader is true, then we have a transparent file header which + int headerLen; - bool perFileIV; - bool externalIVChaining; - uint64_t externalIV; - uint64_t fileIV; - int lastFlags; + bool perFileIV; + bool externalIVChaining; + uint64_t externalIV; + uint64_t fileIV; + int lastFlags; - shared_ptr cipher; + shared_ptr cipher; }; } // namespace encfs diff --git a/fs/Context.cpp b/fs/Context.cpp index a4900a0..44691f0 100644 --- a/fs/Context.cpp +++ b/fs/Context.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -27,67 +27,55 @@ namespace encfs { -EncFS_Context::EncFS_Context() -{ +EncFS_Context::EncFS_Context() { #ifdef CMAKE_USE_PTHREADS_INIT - pthread_cond_init( &wakeupCond, 0 ); + pthread_cond_init(&wakeupCond, 0); #endif usageCount = 0; } -EncFS_Context::~EncFS_Context() -{ +EncFS_Context::~EncFS_Context() { #ifdef CMAKE_USE_PTHREADS_INIT - pthread_cond_destroy( &wakeupCond ); + pthread_cond_destroy(&wakeupCond); #endif // release all entries from map openFiles.clear(); } -shared_ptr EncFS_Context::getRoot(int *errCode) -{ +shared_ptr EncFS_Context::getRoot(int *errCode) { shared_ptr ret; - do - { + do { { - Lock lock( contextMutex ); + Lock lock(contextMutex); ret = root; ++usageCount; } - if(!ret) - { - int res = remountFS( this ); - if(res != 0) - { + if (!ret) { + int res = remountFS(this); + if (res != 0) { *errCode = res; break; } } - } while(!ret); + } while (!ret); return ret; } -void EncFS_Context::setRoot(const shared_ptr &r) -{ - Lock lock( contextMutex ); +void EncFS_Context::setRoot(const shared_ptr &r) { + Lock lock(contextMutex); root = r; - if(r) - rootCipherDir = r->rootDirectory(); + if (r) rootCipherDir = r->rootDirectory(); } -bool EncFS_Context::isMounted() -{ - return root; -} +bool EncFS_Context::isMounted() { return root; } -int EncFS_Context::getAndResetUsageCounter() -{ - Lock lock( contextMutex ); +int EncFS_Context::getAndResetUsageCounter() { + Lock lock(contextMutex); int count = usageCount; usageCount = 0; @@ -95,79 +83,69 @@ int EncFS_Context::getAndResetUsageCounter() return count; } -int EncFS_Context::openFileCount() const -{ - Lock lock( contextMutex ); +int EncFS_Context::openFileCount() const { + Lock lock(contextMutex); return openFiles.size(); } -shared_ptr EncFS_Context::lookupNode(const char *path) -{ - Lock lock( contextMutex ); +shared_ptr EncFS_Context::lookupNode(const char *path) { + Lock lock(contextMutex); - FileMap::iterator it = openFiles.find( std::string(path) ); - if(it != openFiles.end()) - { + FileMap::iterator it = openFiles.find(std::string(path)); + if (it != openFiles.end()) { // all the items in the set point to the same node.. so just use the // first return (*it->second.begin())->node; - } else - { + } else { return shared_ptr(); } } -void EncFS_Context::renameNode(const char *from, const char *to) -{ - Lock lock( contextMutex ); +void EncFS_Context::renameNode(const char *from, const char *to) { + Lock lock(contextMutex); - FileMap::iterator it = openFiles.find( std::string(from) ); - if(it != openFiles.end()) - { + FileMap::iterator it = openFiles.find(std::string(from)); + if (it != openFiles.end()) { std::set val = it->second; openFiles.erase(it); - openFiles[ std::string(to) ] = val; + openFiles[std::string(to)] = val; } } -shared_ptr EncFS_Context::getNode(void *pl) -{ - Placeholder *ph = (Placeholder*)pl; +shared_ptr EncFS_Context::getNode(void *pl) { + Placeholder *ph = (Placeholder *)pl; return ph->node; } -void *EncFS_Context::putNode(const char *path, - const shared_ptr &node) -{ - Lock lock( contextMutex ); - Placeholder *pl = new Placeholder( node ); - openFiles[ std::string(path) ].insert(pl); +void *EncFS_Context::putNode(const char *path, + const shared_ptr &node) { + Lock lock(contextMutex); + Placeholder *pl = new Placeholder(node); + openFiles[std::string(path)].insert(pl); return (void *)pl; } -void EncFS_Context::eraseNode(const char *path, void *pl) -{ - Lock lock( contextMutex ); +void EncFS_Context::eraseNode(const char *path, void *pl) { + Lock lock(contextMutex); Placeholder *ph = (Placeholder *)pl; - FileMap::iterator it = openFiles.find( std::string(path) ); + FileMap::iterator it = openFiles.find(std::string(path)); rAssert(it != openFiles.end()); - int rmCount = it->second.erase( ph ); + int rmCount = it->second.erase(ph); rAssert(rmCount == 1); // if no more references to this file, remove the record all together - if(it->second.empty()) - { + if (it->second.empty()) { // attempts to make use of shallow copy to clear memory used to hold // unencrypted filenames.. not sure this does any good.. std::string storedName = it->first; - openFiles.erase( it ); - storedName.assign( storedName.length(), '\0' ); + openFiles.erase(it); + storedName.assign(storedName.length(), '\0'); } delete ph; diff --git a/fs/Context.h b/fs/Context.h index 00426c3..92ca0cc 100644 --- a/fs/Context.h +++ b/fs/Context.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -43,8 +43,7 @@ struct EncFS_Opts; class FileNode; class DirNode; -class EncFS_Context -{ +class EncFS_Context { public: EncFS_Context(); ~EncFS_Context(); @@ -91,15 +90,14 @@ class EncFS_Context * release() is called. shared_ptr then does our reference counting for * us. */ - struct Placeholder - { + struct Placeholder { shared_ptr node; - Placeholder( const shared_ptr &ptr ) : node(ptr) {} + Placeholder(const shared_ptr &ptr) : node(ptr) {} }; // set of open files, indexed by path - typedef unordered_map > FileMap; + typedef unordered_map > FileMap; #ifdef CMAKE_USE_PTHREADS_INIT mutable Mutex contextMutex; @@ -111,9 +109,8 @@ class EncFS_Context shared_ptr root; }; -int remountFS( EncFS_Context *ctx ); +int remountFS(EncFS_Context *ctx); } // namespace encfs #endif - diff --git a/fs/DirNode.cpp b/fs/DirNode.cpp index 21e5452..8b5ee16 100644 --- a/fs/DirNode.cpp +++ b/fs/DirNode.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -39,7 +39,6 @@ #include "fs/FileUtils.h" #include "fs/fsconfig.pb.h" - #include #include @@ -49,33 +48,19 @@ using std::string; namespace encfs { -class DirDeleter -{ -public: - void operator () ( DIR *d ) - { - ::closedir( d ); - } +class DirDeleter { + public: + void operator()(DIR *d) { ::closedir(d); } }; - -DirTraverse::DirTraverse(const shared_ptr &_dirPtr, - uint64_t _iv, const shared_ptr &_naming) - : dir( _dirPtr ) - , iv( _iv ) - , naming( _naming ) -{ -} +DirTraverse::DirTraverse(const shared_ptr &_dirPtr, uint64_t _iv, + const shared_ptr &_naming) + : dir(_dirPtr), iv(_iv), naming(_naming) {} DirTraverse::DirTraverse(const DirTraverse &src) - : dir( src.dir ) - , iv( src.iv ) - , naming( src.naming ) -{ -} + : dir(src.dir), iv(src.iv), naming(src.naming) {} -DirTraverse &DirTraverse::operator = (const DirTraverse &src) -{ +DirTraverse &DirTraverse::operator=(const DirTraverse &src) { dir = src.dir; iv = src.iv; naming = src.naming; @@ -83,23 +68,18 @@ DirTraverse &DirTraverse::operator = (const DirTraverse &src) return *this; } -DirTraverse::~DirTraverse() -{ +DirTraverse::~DirTraverse() { dir.reset(); iv = 0; naming.reset(); } -static -bool _nextName(struct dirent *&de, const shared_ptr &dir, - int *fileType, ino_t *inode) -{ - de = ::readdir( dir.get() ); +static bool _nextName(struct dirent *&de, const shared_ptr &dir, + int *fileType, ino_t *inode) { + de = ::readdir(dir.get()); - if(de) - { - if(fileType) - { + if (de) { + if (fileType) { #if defined(_DIRENT_HAVE_D_TYPE) || defined(__FreeBSD__) *fileType = de->d_type; #else @@ -107,63 +87,51 @@ bool _nextName(struct dirent *&de, const shared_ptr &dir, *fileType = 0; #endif } - if(inode) - *inode = de->d_ino; + if (inode) *inode = de->d_ino; return true; - } else - { - if(fileType) - *fileType = 0; + } else { + if (fileType) *fileType = 0; return false; } } - -std::string DirTraverse::nextPlaintextName(int *fileType, ino_t *inode) -{ - struct dirent *de=0; - while(_nextName(de, dir, fileType, inode)) - { - try - { +std::string DirTraverse::nextPlaintextName(int *fileType, ino_t *inode) { + struct dirent *de = 0; + while (_nextName(de, dir, fileType, inode)) { + try { uint64_t localIv = iv; - return naming->decodePath( de->d_name, &localIv ); - } catch ( Error &ex ) - { + return naming->decodePath(de->d_name, &localIv); + } + catch (Error &ex) { // .. .problem decoding, ignore it and continue on to next name.. - VLOG(1) << "error decoding filename " << de->d_name - << " : " << ex.what(); + VLOG(1) << "error decoding filename " << de->d_name << " : " << ex.what(); } } return string(); } -std::string DirTraverse::nextInvalid() -{ - struct dirent *de=0; +std::string DirTraverse::nextInvalid() { + struct dirent *de = 0; // find the first name which produces a decoding error... - while(_nextName(de, dir, (int*)0, (ino_t*)0)) - { - try - { + while (_nextName(de, dir, (int *)0, (ino_t *)0)) { + try { uint64_t localIv = iv; - naming->decodePath( de->d_name, &localIv ); + naming->decodePath(de->d_name, &localIv); continue; - } catch( Error &ex ) - { - return string( de->d_name ); + } + catch (Error &ex) { + return string(de->d_name); } } return string(); } -struct RenameEl -{ +struct RenameEl { // ciphertext names string oldCName; - string newCName; // intermediate name (not final cname) + string newCName; // intermediate name (not final cname) // plaintext names string oldPName; @@ -172,59 +140,44 @@ struct RenameEl bool isDirectory; }; -class RenameOp -{ -private: +class RenameOp { + private: DirNode *dn; - shared_ptr< list > renameList; + shared_ptr > renameList; list::const_iterator last; -public: - RenameOp( DirNode *_dn, const shared_ptr< list > &_renameList ) - : dn(_dn), renameList(_renameList) - { + public: + RenameOp(DirNode *_dn, const shared_ptr > &_renameList) + : dn(_dn), renameList(_renameList) { last = renameList->begin(); } RenameOp(const RenameOp &src) - : dn(src.dn) - , renameList(src.renameList) - , last(src.last) - { - } + : dn(src.dn), renameList(src.renameList), last(src.last) {} ~RenameOp(); - operator bool () const - { - return renameList; - } + operator bool() const { return renameList; } bool apply(); void undo(); }; -RenameOp::~RenameOp() -{ - if(renameList) - { +RenameOp::~RenameOp() { + if (renameList) { // got a bunch of decoded filenames sitting in memory.. do a little // cleanup before leaving.. list::iterator it; - for(it = renameList->begin(); it != renameList->end(); ++it) - { - it->oldPName.assign( it->oldPName.size(), ' ' ); - it->newPName.assign( it->newPName.size(), ' ' ); + for (it = renameList->begin(); it != renameList->end(); ++it) { + it->oldPName.assign(it->oldPName.size(), ' '); + it->newPName.assign(it->newPName.size(), ' '); } } } -bool RenameOp::apply() -{ - try - { - while(last != renameList->end()) - { +bool RenameOp::apply() { + try { + while (last != renameList->end()) { // backing store rename. VLOG(2) << "renaming " << last->oldCName << "-> " << last->newCName; @@ -232,22 +185,17 @@ bool RenameOp::apply() bool preserve_mtime = ::stat(last->oldCName.c_str(), &st) == 0; // internal node rename.. - dn->renameNode( last->oldPName.c_str(), - last->newPName.c_str() ); + dn->renameNode(last->oldPName.c_str(), last->newPName.c_str()); // rename on disk.. - if(::rename( last->oldCName.c_str(), - last->newCName.c_str() ) == -1) - { - LOG(WARNING) << "Error renaming " << last->oldCName << ": " << - strerror(errno); - dn->renameNode( last->newPName.c_str(), - last->oldPName.c_str(), false ); + if (::rename(last->oldCName.c_str(), last->newCName.c_str()) == -1) { + LOG(WARNING) << "Error renaming " << last->oldCName << ": " + << strerror(errno); + dn->renameNode(last->newPName.c_str(), last->oldPName.c_str(), false); return false; } - if(preserve_mtime) - { + if (preserve_mtime) { struct utimbuf ut; ut.actime = st.st_atime; ut.modtime = st.st_mtime; @@ -258,21 +206,19 @@ bool RenameOp::apply() } return true; - } catch( Error &err ) - { + } + catch (Error &err) { LOG(WARNING) << "caught error in rename application: " << err.what(); return false; } } -void RenameOp::undo() -{ +void RenameOp::undo() { VLOG(1) << "in undoRename"; - if(last == renameList->begin()) - { + if (last == renameList->begin()) { VLOG(1) << "nothing to undo"; - return; // nothing to undo + return; // nothing to undo } // list has to be processed backwards, otherwise we may rename @@ -281,19 +227,16 @@ void RenameOp::undo() int errorCount = 0; list::const_iterator it = last; - while( it != renameList->begin() ) - { + while (it != renameList->begin()) { --it; VLOG(1) << "undo: renaming " << it->newCName << " -> " << it->oldCName; - ::rename( it->newCName.c_str(), it->oldCName.c_str() ); - try - { - dn->renameNode( it->newPName.c_str(), - it->oldPName.c_str(), false ); - } catch( Error &err ) - { + ::rename(it->newCName.c_str(), it->oldCName.c_str()); + try { + dn->renameNode(it->newPName.c_str(), it->oldPName.c_str(), false); + } + catch (Error &err) { if (++errorCount == 1) LOG(WARNING) << "error in rename und: " << err.what(); // continue on anyway... @@ -304,11 +247,9 @@ void RenameOp::undo() LOG(WARNING) << "Undo rename count: " << undoCount; } -DirNode::DirNode(EncFS_Context *_ctx, - const string &sourceDir, - const FSConfigPtr &_config) -{ - Lock _lock( mutex ); +DirNode::DirNode(EncFS_Context *_ctx, const string &sourceDir, + const FSConfigPtr &_config) { + Lock _lock(mutex); ctx = _ctx; rootDir = sourceDir; @@ -316,169 +257,138 @@ DirNode::DirNode(EncFS_Context *_ctx, // make sure rootDir ends in '/', so that we can form a path by appending // the rest.. - if( rootDir[ rootDir.length()-1 ] != '/' ) - rootDir.append( 1, '/'); + if (rootDir[rootDir.length() - 1] != '/') rootDir.append(1, '/'); naming = fsConfig->nameCoding; } -DirNode::~DirNode() -{ -} +DirNode::~DirNode() {} -bool DirNode::hasDirectoryNameDependency() const -{ +bool DirNode::hasDirectoryNameDependency() const { return naming ? naming->getChainedNameIV() : false; } -string DirNode::rootDirectory() -{ +string DirNode::rootDirectory() { // don't update last access here, otherwise 'du' would cause lastAccess to // be reset. // chop off '/' terminator from root dir. - return string( rootDir, 0, rootDir.length()-1 ); + return string(rootDir, 0, rootDir.length() - 1); } -string DirNode::cipherPath( const char *plaintextPath ) -{ - return rootDir + naming->encodePath( plaintextPath ); +string DirNode::cipherPath(const char *plaintextPath) { + return rootDir + naming->encodePath(plaintextPath); } -string DirNode::cipherPathWithoutRoot( const char *plaintextPath ) -{ - return naming->encodePath( plaintextPath ); +string DirNode::cipherPathWithoutRoot(const char *plaintextPath) { + return naming->encodePath(plaintextPath); } -string DirNode::plainPath( const char *cipherPath_ ) -{ - try - { - if( !strncmp( cipherPath_, rootDir.c_str(), - rootDir.length() ) ) - { - return naming->decodePath( cipherPath_ + rootDir.length() ); - } else - { - if ( cipherPath_[0] == '+' ) - { +string DirNode::plainPath(const char *cipherPath_) { + try { + if (!strncmp(cipherPath_, rootDir.c_str(), rootDir.length())) { + return naming->decodePath(cipherPath_ + rootDir.length()); + } else { + if (cipherPath_[0] == '+') { // decode as fully qualified path - return string("/") + naming->decodeName( cipherPath_+1, - strlen(cipherPath_+1) ); - } else - { - return naming->decodePath( cipherPath_ ); + return string("/") + + naming->decodeName(cipherPath_ + 1, strlen(cipherPath_ + 1)); + } else { + return naming->decodePath(cipherPath_); } } - - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "decode err: " << err.what(); return string(); } } -string DirNode::relativeCipherPath( const char *plaintextPath ) -{ - try - { - if(plaintextPath[0] == '/') - { +string DirNode::relativeCipherPath(const char *plaintextPath) { + try { + if (plaintextPath[0] == '/') { // mark with '+' to indicate special decoding.. - return string("+") + naming->encodeName(plaintextPath+1, - strlen(plaintextPath+1)); - } else - { - return naming->encodePath( plaintextPath ); + return string("+") + + naming->encodeName(plaintextPath + 1, strlen(plaintextPath + 1)); + } else { + return naming->encodePath(plaintextPath); } - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "encode err: " << err.what(); return string(); } } -DirTraverse DirNode::openDir(const char *plaintextPath) -{ - string cyName = rootDir + naming->encodePath( plaintextPath ); - //rDebug("openDir on %s", cyName.c_str() ); +DirTraverse DirNode::openDir(const char *plaintextPath) { + string cyName = rootDir + naming->encodePath(plaintextPath); + // rDebug("openDir on %s", cyName.c_str() ); - DIR *dir = ::opendir( cyName.c_str() ); - if(dir == NULL) - { + DIR *dir = ::opendir(cyName.c_str()); + if (dir == NULL) { VLOG(1) << "opendir error " << strerror(errno); - return DirTraverse( shared_ptr(), 0, shared_ptr() ); - } else - { - shared_ptr dp( dir, DirDeleter() ); + return DirTraverse(shared_ptr(), 0, shared_ptr()); + } else { + shared_ptr dp(dir, DirDeleter()); uint64_t iv = 0; // if we're using chained IV mode, then compute the IV at this // directory level.. - try - { - if( naming->getChainedNameIV() ) - naming->encodePath( plaintextPath, &iv ); - } catch( Error &err ) - { + try { + if (naming->getChainedNameIV()) naming->encodePath(plaintextPath, &iv); + } + catch (Error &err) { LOG(ERROR) << "encode err: " << err.what(); } - return DirTraverse( dp, iv, naming ); + return DirTraverse(dp, iv, naming); } } -bool DirNode::genRenameList( list &renameList, - const char *fromP, const char *toP ) -{ +bool DirNode::genRenameList(list &renameList, const char *fromP, + const char *toP) { uint64_t fromIV = 0, toIV = 0; // compute the IV for both paths - string fromCPart = naming->encodePath( fromP, &fromIV ); - string toCPart = naming->encodePath( toP, &toIV ); + string fromCPart = naming->encodePath(fromP, &fromIV); + string toCPart = naming->encodePath(toP, &toIV); // where the files live before the rename.. string sourcePath = rootDir + fromCPart; // ok..... we wish it was so simple.. should almost never happen - if(fromIV == toIV) - return true; + if (fromIV == toIV) return true; // generate the real destination path, where we expect to find the files.. VLOG(1) << "opendir " << sourcePath; - shared_ptr dir = shared_ptr( - opendir( sourcePath.c_str() ), DirDeleter() ); - if(!dir) - return false; + shared_ptr dir = + shared_ptr(opendir(sourcePath.c_str()), DirDeleter()); + if (!dir) return false; struct dirent *de = NULL; - while((de = ::readdir( dir.get() )) != NULL) - { + while ((de = ::readdir(dir.get())) != NULL) { // decode the name using the oldIV uint64_t localIV = fromIV; string plainName; - if((de->d_name[0] == '.') && - ((de->d_name[1] == '\0') - || ((de->d_name[1] == '.') && (de->d_name[2] == '\0')))) - { + if ((de->d_name[0] == '.') && + ((de->d_name[1] == '\0') || + ((de->d_name[1] == '.') && (de->d_name[2] == '\0')))) { // skip "." and ".." continue; } - try - { - plainName = naming->decodePath( de->d_name, &localIV ); - } catch( Error &ex ) - { + try { + plainName = naming->decodePath(de->d_name, &localIV); + } + catch (Error &ex) { // if filename can't be decoded, then ignore it.. continue; } // any error in the following will trigger a rename failure. - try - { + try { // re-encode using the new IV.. localIV = toIV; - string newName = naming->encodePath( plainName.c_str(), &localIV ); + string newName = naming->encodePath(plainName.c_str(), &localIV); // store rename information.. string oldFull = sourcePath + '/' + de->d_name; @@ -492,38 +402,34 @@ bool DirNode::genRenameList( list &renameList, bool isDir; #if defined(_DIRENT_HAVE_D_TYPE) - if(de->d_type != DT_UNKNOWN) - { + if (de->d_type != DT_UNKNOWN) { isDir = (de->d_type == DT_DIR); } else #endif { - isDir = isDirectory( oldFull.c_str() ); + isDir = isDirectory(oldFull.c_str()); } ren.isDirectory = isDir; - if(isDir) - { + if (isDir) { // recurse.. We want to add subdirectory elements before the // parent, as that is the logical rename order.. - if(!genRenameList( renameList, - ren.oldPName.c_str(), - ren.newPName.c_str())) - { + if (!genRenameList(renameList, ren.oldPName.c_str(), + ren.newPName.c_str())) { return false; } } VLOG(1) << "adding file " << oldFull << " to rename list"; - renameList.push_back( ren ); - - } catch( Error &err ) - { + renameList.push_back(ren); + } + catch (Error &err) { // We can't convert this name, because we don't have a valid IV for // it (or perhaps a valid key).. It will be inaccessible.. - LOG(WARNING) << "Aborting rename: error on file " << - fromCPart.append(1, '/').append(de->d_name) << ":" << err.what(); + LOG(WARNING) << "Aborting rename: error on file " + << fromCPart.append(1, '/').append(de->d_name) << ":" + << err.what(); // abort.. Err on the side of safety and disallow rename, rather // then loosing files.. @@ -534,7 +440,6 @@ bool DirNode::genRenameList( list &renameList, return true; } - /* A bit of a pain.. If a directory is renamed in a filesystem with directory initialization vector chaining, then we have to recursively @@ -543,49 +448,39 @@ bool DirNode::genRenameList( list &renameList, Returns a list of renamed items on success, a null list on failure. */ -shared_ptr -DirNode::newRenameOp( const char *fromP, const char *toP ) -{ +shared_ptr DirNode::newRenameOp(const char *fromP, const char *toP) { // Do the rename in two stages to avoid chasing our tail // Undo everything if we encounter an error! - shared_ptr< list > renameList(new list); - if(!genRenameList( *renameList.get(), fromP, toP )) - { + shared_ptr > renameList(new list); + if (!genRenameList(*renameList.get(), fromP, toP)) { LOG(WARNING) << "Error during generation of recursive rename list"; return shared_ptr(); } else - return shared_ptr( new RenameOp(this, renameList) ); + return shared_ptr(new RenameOp(this, renameList)); } - -int DirNode::mkdir(const char *plaintextPath, mode_t mode, - uid_t uid, gid_t gid) -{ - string cyName = rootDir + naming->encodePath( plaintextPath ); - rAssert( !cyName.empty() ); +int DirNode::mkdir(const char *plaintextPath, mode_t mode, uid_t uid, + gid_t gid) { + string cyName = rootDir + naming->encodePath(plaintextPath); + rAssert(!cyName.empty()); VLOG(1) << "mkdir on " << cyName; // if uid or gid are set, then that should be the directory owner int olduid = -1; int oldgid = -1; - if(uid != 0) - olduid = setfsuid( uid ); - if(gid != 0) - oldgid = setfsgid( gid ); + if (uid != 0) olduid = setfsuid(uid); + if (gid != 0) oldgid = setfsgid(gid); - int res = ::mkdir( cyName.c_str(), mode ); + int res = ::mkdir(cyName.c_str(), mode); - if(olduid >= 0) - setfsuid( olduid ); - if(oldgid >= 0) - setfsgid( oldgid ); + if (olduid >= 0) setfsuid(olduid); + if (oldgid >= 0) setfsgid(oldgid); - if(res == -1) - { + if (res == -1) { int eno = errno; - LOG(WARNING) << "mkdir error on " << cyName - << " mode " << mode << ": " << strerror(eno); + LOG(WARNING) << "mkdir error on " << cyName << " mode " << mode << ": " + << strerror(eno); res = -eno; } else res = 0; @@ -593,30 +488,25 @@ int DirNode::mkdir(const char *plaintextPath, mode_t mode, return res; } -int -DirNode::rename( const char *fromPlaintext, const char *toPlaintext ) -{ - Lock _lock( mutex ); +int DirNode::rename(const char *fromPlaintext, const char *toPlaintext) { + Lock _lock(mutex); - string fromCName = rootDir + naming->encodePath( fromPlaintext ); - string toCName = rootDir + naming->encodePath( toPlaintext ); - rAssert( !fromCName.empty() ); - rAssert( !toCName.empty() ); + string fromCName = rootDir + naming->encodePath(fromPlaintext); + string toCName = rootDir + naming->encodePath(toPlaintext); + rAssert(!fromCName.empty()); + rAssert(!toCName.empty()); VLOG(1) << "rename " << fromCName << " -> " << toCName; - shared_ptr toNode = findOrCreate( toPlaintext ); + shared_ptr toNode = findOrCreate(toPlaintext); shared_ptr renameOp; - if( hasDirectoryNameDependency() && isDirectory( fromCName.c_str() )) - { + if (hasDirectoryNameDependency() && isDirectory(fromCName.c_str())) { VLOG(1) << "recursive rename begin"; - renameOp = newRenameOp( fromPlaintext, toPlaintext ); + renameOp = newRenameOp(fromPlaintext, toPlaintext); - if(!renameOp || !renameOp->apply()) - { - if(renameOp) - renameOp->undo(); + if (!renameOp || !renameOp->apply()) { + if (renameOp) renameOp->undo(); LOG(WARNING) << "rename aborted"; return -EACCES; @@ -625,65 +515,57 @@ DirNode::rename( const char *fromPlaintext, const char *toPlaintext ) } int res = 0; - try - { + try { struct stat st; bool preserve_mtime = ::stat(fromCName.c_str(), &st) == 0; - renameNode( fromPlaintext, toPlaintext ); - res = ::rename( fromCName.c_str(), toCName.c_str() ); + renameNode(fromPlaintext, toPlaintext); + res = ::rename(fromCName.c_str(), toCName.c_str()); - if(res == -1) - { + if (res == -1) { // undo res = -errno; - renameNode( toPlaintext, fromPlaintext, false ); + renameNode(toPlaintext, fromPlaintext, false); - if(renameOp) - renameOp->undo(); - } else if(preserve_mtime) - { + if (renameOp) renameOp->undo(); + } else if (preserve_mtime) { struct utimbuf ut; ut.actime = st.st_atime; ut.modtime = st.st_mtime; ::utime(toCName.c_str(), &ut); } - } catch( Error &err ) - { + } + catch (Error &err) { // exception from renameNode, just show the error and continue.. LOG(ERROR) << "rename err: " << err.what(); res = -EIO; } - if(res != 0) - { - VLOG(1) << "rename failed: " << strerror( errno ); + if (res != 0) { + VLOG(1) << "rename failed: " << strerror(errno); res = -errno; } return res; } -int DirNode::link( const char *from, const char *to ) -{ - Lock _lock( mutex ); +int DirNode::link(const char *from, const char *to) { + Lock _lock(mutex); - string fromCName = rootDir + naming->encodePath( from ); - string toCName = rootDir + naming->encodePath( to ); + string fromCName = rootDir + naming->encodePath(from); + string toCName = rootDir + naming->encodePath(to); - rAssert( !fromCName.empty() ); - rAssert( !toCName.empty() ); + rAssert(!fromCName.empty()); + rAssert(!toCName.empty()); VLOG(1) << "link " << fromCName << " -> " << toCName; int res = -EPERM; - if( fsConfig->config->external_iv() ) - { + if (fsConfig->config->external_iv()) { VLOG(1) << "hard links not supported with external IV chaining!"; - } else - { - res = ::link( fromCName.c_str(), toCName.c_str() ); - if(res == -1) + } else { + res = ::link(fromCName.c_str(), toCName.c_str()); + if (res == -1) res = -errno; else res = 0; @@ -696,31 +578,25 @@ int DirNode::link( const char *from, const char *to ) The node is keyed by filename, so a rename means the internal node names must be changed. */ -shared_ptr DirNode::renameNode( const char *from, const char *to ) -{ - return renameNode( from, to, true ); +shared_ptr DirNode::renameNode(const char *from, const char *to) { + return renameNode(from, to, true); } -shared_ptr DirNode::renameNode( const char *from, const char *to, - bool forwardMode ) -{ - shared_ptr node = findOrCreate( from ); +shared_ptr DirNode::renameNode(const char *from, const char *to, + bool forwardMode) { + shared_ptr node = findOrCreate(from); - if(node) - { + if (node) { uint64_t newIV = 0; - string cname = rootDir + naming->encodePath( to, &newIV ); + string cname = rootDir + naming->encodePath(to, &newIV); - VLOG(1) << "renaming internal node " << node->cipherName() - << " -> " << cname.c_str(); + VLOG(1) << "renaming internal node " << node->cipherName() << " -> " + << cname.c_str(); - if(node->setName( to, cname.c_str(), newIV, forwardMode )) - { - if(ctx) - ctx->renameNode( from, to ); - } else - { - // rename error! - put it back + if (node->setName(to, cname.c_str(), newIV, forwardMode)) { + if (ctx) ctx->renameNode(from, to); + } else { + // rename error! - put it back LOG(ERROR) << "renameNode failed"; throw Error("Internal node name change failed!"); } @@ -729,22 +605,17 @@ shared_ptr DirNode::renameNode( const char *from, const char *to, return node; } -shared_ptr DirNode::findOrCreate( const char *plainName) -{ +shared_ptr DirNode::findOrCreate(const char *plainName) { shared_ptr node; - if(ctx) - node = ctx->lookupNode( plainName ); + if (ctx) node = ctx->lookupNode(plainName); - if(!node) - { + if (!node) { uint64_t iv = 0; - string cipherName = naming->encodePath( plainName, &iv ); - node.reset( new FileNode( this, fsConfig, - plainName, - (rootDir + cipherName).c_str())); + string cipherName = naming->encodePath(plainName, &iv); + node.reset(new FileNode(this, fsConfig, plainName, + (rootDir + cipherName).c_str())); - if(fsConfig->config->external_iv()) - node->setName(0, 0, iv); + if (fsConfig->config->external_iv()) node->setName(0, 0, iv); VLOG(1) << "created FileNode for " << node->cipherName(); } @@ -752,13 +623,12 @@ shared_ptr DirNode::findOrCreate( const char *plainName) return node; } -shared_ptr -DirNode::lookupNode( const char *plainName, const char * requestor ) -{ +shared_ptr DirNode::lookupNode(const char *plainName, + const char *requestor) { (void)requestor; - Lock _lock( mutex ); + Lock _lock(mutex); - shared_ptr node = findOrCreate( plainName ); + shared_ptr node = findOrCreate(plainName); return node; } @@ -768,51 +638,45 @@ DirNode::lookupNode( const char *plainName, const char * requestor ) node on sucess.. This is done in one step to avoid any race conditions with the stored state of the file. */ -shared_ptr -DirNode::openNode( const char *plainName, const char * requestor, int flags, - int *result ) -{ +shared_ptr DirNode::openNode(const char *plainName, + const char *requestor, int flags, + int *result) { (void)requestor; - rAssert( result != NULL ); - Lock _lock( mutex ); + rAssert(result != NULL); + Lock _lock(mutex); - shared_ptr node = findOrCreate( plainName ); + shared_ptr node = findOrCreate(plainName); - if( node && (*result = node->open( flags )) >= 0 ) + if (node && (*result = node->open(flags)) >= 0) return node; else return shared_ptr(); } -int DirNode::unlink( const char *plaintextName ) -{ - string cyName = naming->encodePath( plaintextName ); +int DirNode::unlink(const char *plaintextName) { + string cyName = naming->encodePath(plaintextName); VLOG(1) << "unlink " << cyName; - Lock _lock( mutex ); + Lock _lock(mutex); int res = 0; - if(ctx && ctx->lookupNode( plaintextName )) - { + if (ctx && ctx->lookupNode(plaintextName)) { // If FUSE is running with "hard_remove" option where it doesn't // hide open files for us, then we can't allow an unlink of an open // file.. - LOG(WARNING) << "Refusing to unlink open file: " - << cyName << ", hard_remove option is probably in effect"; + LOG(WARNING) << "Refusing to unlink open file: " << cyName + << ", hard_remove option is probably in effect"; res = -EBUSY; - } else - { + } else { string fullName = rootDir + cyName; - res = ::unlink( fullName.c_str() ); - if(res == -1) - { + res = ::unlink(fullName.c_str()); + if (res == -1) { res = -errno; VLOG(1) << "unlink error: " << strerror(errno); - } + } } return res; } } // namespace encfs - diff --git a/fs/DirNode.h b/fs/DirNode.h index 7360536..0e96c45 100644 --- a/fs/DirNode.h +++ b/fs/DirNode.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -44,133 +44,129 @@ class RenameOp; struct RenameEl; class EncFS_Context; -class DirTraverse -{ -public: - DirTraverse(const shared_ptr &dirPtr, uint64_t iv, - const shared_ptr &naming); - DirTraverse(const DirTraverse &src); - ~DirTraverse(); +class DirTraverse { + public: + DirTraverse(const shared_ptr &dirPtr, uint64_t iv, + const shared_ptr &naming); + DirTraverse(const DirTraverse &src); + ~DirTraverse(); - DirTraverse &operator = (const DirTraverse &src); + DirTraverse &operator=(const DirTraverse &src); - // returns FALSE to indicate an invalid DirTraverse (such as when - // an invalid directory is requested for traversal) - bool valid() const; + // returns FALSE to indicate an invalid DirTraverse (such as when + // an invalid directory is requested for traversal) + bool valid() const; - // return next plaintext filename - // If fileType is not 0, then it is used to return the filetype (or 0 if - // unknown) - std::string nextPlaintextName(int *fileType=0, ino_t *inode=0); + // return next plaintext filename + // If fileType is not 0, then it is used to return the filetype (or 0 if + // unknown) + std::string nextPlaintextName(int *fileType = 0, ino_t *inode = 0); - /* Return cipher name of next undecodable filename.. - The opposite of nextPlaintextName(), as that skips undecodable names.. - */ - std::string nextInvalid(); -private: + /* Return cipher name of next undecodable filename.. + The opposite of nextPlaintextName(), as that skips undecodable names.. + */ + std::string nextInvalid(); - shared_ptr dir; // struct DIR - // initialization vector to use. Not very general purpose, but makes it - // more efficient to support filename IV chaining.. - uint64_t iv; - shared_ptr naming; + private: + shared_ptr dir; // struct DIR + // initialization vector to use. Not very general purpose, but makes it + // more efficient to support filename IV chaining.. + uint64_t iv; + shared_ptr naming; }; inline bool DirTraverse::valid() const { return dir != 0; } -class DirNode -{ -public: - // sourceDir points to where raw files are stored - DirNode(EncFS_Context *ctx, - const std::string &sourceDir, - const FSConfigPtr &config ); - ~DirNode(); +class DirNode { + public: + // sourceDir points to where raw files are stored + DirNode(EncFS_Context *ctx, const std::string &sourceDir, + const FSConfigPtr &config); + ~DirNode(); - // return the path to the root directory - std::string rootDirectory(); + // return the path to the root directory + std::string rootDirectory(); - // find files - shared_ptr lookupNode( const char *plaintextName, - const char *requestor ); + // find files + shared_ptr lookupNode(const char *plaintextName, + const char *requestor); - /* - Combined lookupNode + node->open() call. If the open fails, then the - node is not retained. If the open succeeds, then the node is returned. - */ - shared_ptr openNode( const char *plaintextName, - const char *requestor, int flags, int *openResult ); + /* + Combined lookupNode + node->open() call. If the open fails, then the + node is not retained. If the open succeeds, then the node is returned. + */ + shared_ptr openNode(const char *plaintextName, + const char *requestor, int flags, + int *openResult); - std::string cipherPath( const char *plaintextPath ); - std::string cipherPathWithoutRoot( const char *plaintextPath ); - std::string plainPath( const char *cipherPath ); + std::string cipherPath(const char *plaintextPath); + std::string cipherPathWithoutRoot(const char *plaintextPath); + std::string plainPath(const char *cipherPath); - // relative cipherPath is the same as cipherPath except that it doesn't - // prepent the mount point. That it, it doesn't return a fully qualified - // name, just a relative path within the encrypted filesystem. - std::string relativeCipherPath( const char *plaintextPath ); + // relative cipherPath is the same as cipherPath except that it doesn't + // prepent the mount point. That it, it doesn't return a fully qualified + // name, just a relative path within the encrypted filesystem. + std::string relativeCipherPath(const char *plaintextPath); - /* - Returns true if file names are dependent on the parent directory name. - If a directory name is changed, then all the filenames must also be - changed. - */ - bool hasDirectoryNameDependency() const; + /* + Returns true if file names are dependent on the parent directory name. + If a directory name is changed, then all the filenames must also be + changed. + */ + bool hasDirectoryNameDependency() const; - // unlink the specified file - int unlink( const char *plaintextName ); + // unlink the specified file + int unlink(const char *plaintextName); - // traverse directory - DirTraverse openDir( const char *plainDirName ); + // traverse directory + DirTraverse openDir(const char *plainDirName); - // uid and gid are used as the directory owner, only if not zero - int mkdir( const char *plaintextPath, mode_t mode, - uid_t uid = 0, gid_t gid = 0); + // uid and gid are used as the directory owner, only if not zero + int mkdir(const char *plaintextPath, mode_t mode, uid_t uid = 0, + gid_t gid = 0); - int rename( const char *fromPlaintext, const char *toPlaintext ); + int rename(const char *fromPlaintext, const char *toPlaintext); - int link( const char *from, const char *to ); - - // returns idle time of filesystem in seconds - int idleSeconds(); + int link(const char *from, const char *to); -protected: + // returns idle time of filesystem in seconds + int idleSeconds(); - /* - notify that a file is being renamed. - This renames the internal node, if any. If the file is not open, then - this call has no effect. - Returns the FileNode if it was found. - */ - shared_ptr renameNode( const char *from, const char *to ); - shared_ptr renameNode( const char *from, const char *to, - bool forwardMode ); + protected: + /* + notify that a file is being renamed. + This renames the internal node, if any. If the file is not open, then + this call has no effect. + Returns the FileNode if it was found. + */ + shared_ptr renameNode(const char *from, const char *to); + shared_ptr renameNode(const char *from, const char *to, + bool forwardMode); - /* - when directory IV chaining is enabled, a directory can't be renamed - without renaming all its contents as well. recursiveRename should be - called after renaming the directory, passing in the plaintext from and - to paths. - */ - shared_ptr newRenameOp( const char *from, const char *to ); + /* + when directory IV chaining is enabled, a directory can't be renamed + without renaming all its contents as well. recursiveRename should be + called after renaming the directory, passing in the plaintext from and + to paths. + */ + shared_ptr newRenameOp(const char *from, const char *to); -private: + private: + friend class RenameOp; - friend class RenameOp; + bool genRenameList(std::list &list, const char *fromP, + const char *toP); - bool genRenameList( std::list &list, const char *fromP, - const char *toP ); - - shared_ptr findOrCreate( const char *plainName); + shared_ptr findOrCreate(const char *plainName); - Mutex mutex; + Mutex mutex; - EncFS_Context *ctx; + EncFS_Context *ctx; - // passed in as configuration - std::string rootDir; - FSConfigPtr fsConfig; + // passed in as configuration + std::string rootDir; + FSConfigPtr fsConfig; - shared_ptr naming; + shared_ptr naming; }; } // namespace encfs diff --git a/fs/FSConfig.h b/fs/FSConfig.h index 94d1bea..a38a814 100644 --- a/fs/FSConfig.h +++ b/fs/FSConfig.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -31,15 +31,14 @@ namespace encfs { -enum ConfigType -{ - Config_None = 0, - Config_Prehistoric, - Config_V3 = 3, - Config_V4 = 4, - Config_V5 = 5, - Config_V6 = 6, - Config_V7 = 7 +enum ConfigType { + Config_None = 0, + Config_Prehistoric, + Config_V3 = 3, + Config_V4 = 4, + Config_V5 = 5, + Config_V6 = 6, + Config_V7 = 7 }; struct EncFS_Opts; @@ -51,35 +50,32 @@ CipherKey getUserKey(const EncfsConfig &config, const std::string &passwordProgram, const std::string &rootDir); -CipherKey getNewUserKey(EncfsConfig &config, bool useStdin, - const std::string &program, const std::string &rootDir); - +CipherKey getNewUserKey(EncfsConfig &config, bool useStdin, + const std::string &program, const std::string &rootDir); + shared_ptr getCipher(const EncfsConfig &cfg); shared_ptr getCipher(const Interface &iface, int keySize); // helpers for serializing to/from a stream -std::ostream &operator << (std::ostream &os, const EncfsConfig &cfg); -std::istream &operator >> (std::istream &os, EncfsConfig &cfg); +std::ostream &operator<<(std::ostream &os, const EncfsConfig &cfg); +std::istream &operator>>(std::istream &os, EncfsConfig &cfg); // Filesystem state -struct FSConfig -{ - shared_ptr config; - shared_ptr opts; +struct FSConfig { + shared_ptr config; + shared_ptr opts; - shared_ptr cipher; - CipherKey key; - shared_ptr nameCoding; + shared_ptr cipher; + CipherKey key; + shared_ptr nameCoding; - bool forceDecode; // force decode on MAC block failures - bool reverseEncryption; // reverse encryption operation + bool forceDecode; // force decode on MAC block failures + bool reverseEncryption; // reverse encryption operation - bool idleTracking; // turn on idle monitoring of filesystem + bool idleTracking; // turn on idle monitoring of filesystem - FSConfig() - : forceDecode(false), - reverseEncryption(false), - idleTracking(false) { } + FSConfig() + : forceDecode(false), reverseEncryption(false), idleTracking(false) {} }; typedef shared_ptr FSConfigPtr; @@ -87,4 +83,3 @@ typedef shared_ptr FSConfigPtr; } // namespace encfs #endif - diff --git a/fs/FileIO.cpp b/fs/FileIO.cpp index 7f44bb0..e414c1c 100644 --- a/fs/FileIO.cpp +++ b/fs/FileIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -22,23 +22,15 @@ namespace encfs { -FileIO::FileIO() -{ -} +FileIO::FileIO() {} -FileIO::~FileIO() -{ -} +FileIO::~FileIO() {} -int FileIO::blockSize() const -{ - return 1; -} +int FileIO::blockSize() const { return 1; } -bool FileIO::setIV( uint64_t iv ) -{ - (void)iv; - return true; +bool FileIO::setIV(uint64_t iv) { + (void)iv; + return true; } } // namespace encfs diff --git a/fs/FileIO.h b/fs/FileIO.h index dca4831..f94b78b 100644 --- a/fs/FileIO.h +++ b/fs/FileIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -28,63 +28,56 @@ namespace encfs { -struct IORequest -{ - off_t offset; +struct IORequest { + off_t offset; - // amount of bytes to read/write. - int dataLen; - unsigned char *data; + // amount of bytes to read/write. + int dataLen; + unsigned char *data; - IORequest(); + IORequest(); }; -inline IORequest::IORequest() - : offset(0) - , dataLen(0) - , data(0) -{ -} +inline IORequest::IORequest() : offset(0), dataLen(0), data(0) {} -class FileIO -{ -public: - FileIO(); - virtual ~FileIO(); +class FileIO { + public: + FileIO(); + virtual ~FileIO(); - virtual Interface interface() const =0; + virtual Interface interface() const = 0; - // default implementation returns 1, meaning this is not block oriented. - virtual int blockSize() const; + // default implementation returns 1, meaning this is not block oriented. + virtual int blockSize() const; - virtual void setFileName(const char *fileName) =0; - virtual const char *getFileName() const =0; + virtual void setFileName(const char *fileName) = 0; + virtual const char *getFileName() const = 0; - // Not sure about this -- it is specific to CipherFileIO, but the - // alternative methods of exposing this interface aren't much nicer.. - virtual bool setIV( uint64_t iv ); + // Not sure about this -- it is specific to CipherFileIO, but the + // alternative methods of exposing this interface aren't much nicer.. + virtual bool setIV(uint64_t iv); - // open file for specified mode. There is no corresponding close, so a - // file is open until the FileIO interface is destroyed. - virtual int open( int flags ) =0; - - // get filesystem attributes for a file - virtual int getAttr( struct stat *stbuf ) const =0; - virtual off_t getSize( ) const =0; + // open file for specified mode. There is no corresponding close, so a + // file is open until the FileIO interface is destroyed. + virtual int open(int flags) = 0; - virtual ssize_t read( const IORequest &req ) const =0; - virtual bool write( const IORequest &req ) =0; + // get filesystem attributes for a file + virtual int getAttr(struct stat *stbuf) const = 0; + virtual off_t getSize() const = 0; - virtual int truncate( off_t size ) =0; + virtual ssize_t read(const IORequest &req) const = 0; + virtual bool write(const IORequest &req) = 0; - virtual bool isWritable() const =0; -private: - // not implemented.. - FileIO( const FileIO & ); - FileIO &operator = ( const FileIO & ); + virtual int truncate(off_t size) = 0; + + virtual bool isWritable() const = 0; + + private: + // not implemented.. + FileIO(const FileIO &); + FileIO &operator=(const FileIO &); }; } // namespace encfs #endif - diff --git a/fs/FileNode.cpp b/fs/FileNode.cpp index 1895f07..8ec379d 100644 --- a/fs/FileNode.cpp +++ b/fs/FileNode.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -63,9 +63,8 @@ namespace encfs { */ FileNode::FileNode(DirNode *parent_, const FSConfigPtr &cfg, - const char *plaintextName_, const char *cipherName_) -{ - Lock _lock( mutex ); + const char *plaintextName_, const char *cipherName_) { + Lock _lock(mutex); this->_pname = plaintextName_; this->_cname = cipherName_; @@ -74,79 +73,59 @@ FileNode::FileNode(DirNode *parent_, const FSConfigPtr &cfg, this->fsConfig = cfg; // chain RawFileIO & CipherFileIO - shared_ptr rawIO( new RawFileIO( _cname ) ); - io = shared_ptr( new CipherFileIO( rawIO, fsConfig )); + shared_ptr rawIO(new RawFileIO(_cname)); + io = shared_ptr(new CipherFileIO(rawIO, fsConfig)); - if(cfg->config->block_mac_bytes() || cfg->config->block_mac_rand_bytes()) + if (cfg->config->block_mac_bytes() || cfg->config->block_mac_rand_bytes()) io = shared_ptr(new MACFileIO(io, fsConfig)); } -FileNode::~FileNode() -{ +FileNode::~FileNode() { // FileNode mutex should be locked before the destructor is called - _pname.assign( _pname.length(), '\0' ); - _cname.assign( _cname.length(), '\0' ); + _pname.assign(_pname.length(), '\0'); + _cname.assign(_cname.length(), '\0'); io.reset(); } -const char *FileNode::cipherName() const -{ - return _cname.c_str(); -} +const char *FileNode::cipherName() const { return _cname.c_str(); } -const char *FileNode::plaintextName() const -{ - return _pname.c_str(); -} +const char *FileNode::plaintextName() const { return _pname.c_str(); } -string FileNode::plaintextParent() const -{ - return parentDirectory( _pname ); -} +string FileNode::plaintextParent() const { return parentDirectory(_pname); } -static bool setIV(const shared_ptr &io, uint64_t iv) -{ +static bool setIV(const shared_ptr &io, uint64_t iv) { struct stat stbuf; - if((io->getAttr(&stbuf) < 0) || S_ISREG(stbuf.st_mode)) - return io->setIV( iv ); + if ((io->getAttr(&stbuf) < 0) || S_ISREG(stbuf.st_mode)) + return io->setIV(iv); else return true; } -bool FileNode::setName( const char *plaintextName_, const char *cipherName_, - uint64_t iv, bool setIVFirst ) -{ - //Lock _lock( mutex ); +bool FileNode::setName(const char *plaintextName_, const char *cipherName_, + uint64_t iv, bool setIVFirst) { + // Lock _lock( mutex ); VLOG(1) << "calling setIV on " << cipherName_; - if(setIVFirst) - { - if(fsConfig->config->external_iv() && !setIV(io, iv)) - return false; + if (setIVFirst) { + if (fsConfig->config->external_iv() && !setIV(io, iv)) return false; // now change the name.. - if(plaintextName_) - this->_pname = plaintextName_; - if(cipherName_) - { + if (plaintextName_) this->_pname = plaintextName_; + if (cipherName_) { this->_cname = cipherName_; - io->setFileName( cipherName_ ); + io->setFileName(cipherName_); } - } else - { + } else { std::string oldPName = _pname; std::string oldCName = _cname; - if(plaintextName_) - this->_pname = plaintextName_; - if(cipherName_) - { + if (plaintextName_) this->_pname = plaintextName_; + if (cipherName_) { this->_cname = cipherName_; - io->setFileName( cipherName_ ); + io->setFileName(cipherName_); } - if(fsConfig->config->external_iv() && !setIV(io, iv)) - { + if (fsConfig->config->external_iv() && !setIV(io, iv)) { _pname = oldPName; _cname = oldCName; return false; @@ -156,27 +135,22 @@ bool FileNode::setName( const char *plaintextName_, const char *cipherName_, return true; } -int FileNode::mknod(mode_t mode, dev_t rdev, uid_t uid, gid_t gid) -{ - Lock _lock( mutex ); +int FileNode::mknod(mode_t mode, dev_t rdev, uid_t uid, gid_t gid) { + Lock _lock(mutex); int res; int olduid = -1; int oldgid = -1; - if(uid != 0) - { - olduid = setfsuid( uid ); - if(olduid == -1) - { + if (uid != 0) { + olduid = setfsuid(uid); + if (olduid == -1) { LOG(INFO) << "setfsuid error: " << strerror(errno); return -EPERM; } } - if(gid != 0) - { - oldgid = setfsgid( gid ); - if(oldgid == -1) - { + if (gid != 0) { + oldgid = setfsgid(gid); + if (oldgid == -1) { LOG(INFO) << "setfsgid error: " << strerror(errno); return -EPERM; } @@ -187,22 +161,18 @@ int FileNode::mknod(mode_t mode, dev_t rdev, uid_t uid, gid_t gid) * The regular file stuff could be stripped off if there * were a create method (advised to have) */ - if (S_ISREG( mode )) { - res = ::open( _cname.c_str(), O_CREAT | O_EXCL | O_WRONLY, mode ); - if (res >= 0) - res = ::close( res ); - } else if (S_ISFIFO( mode )) - res = ::mkfifo( _cname.c_str(), mode ); + if (S_ISREG(mode)) { + res = ::open(_cname.c_str(), O_CREAT | O_EXCL | O_WRONLY, mode); + if (res >= 0) res = ::close(res); + } else if (S_ISFIFO(mode)) + res = ::mkfifo(_cname.c_str(), mode); else - res = ::mknod( _cname.c_str(), mode, rdev ); + res = ::mknod(_cname.c_str(), mode, rdev); - if(olduid >= 0) - setfsuid( olduid ); - if(oldgid >= 0) - setfsgid( oldgid ); + if (olduid >= 0) setfsuid(olduid); + if (oldgid >= 0) setfsgid(oldgid); - if(res == -1) - { + if (res == -1) { int eno = errno; VLOG(1) << "mknod error: " << strerror(eno); res = -eno; @@ -211,85 +181,75 @@ int FileNode::mknod(mode_t mode, dev_t rdev, uid_t uid, gid_t gid) return res; } -int FileNode::open(int flags) const -{ - Lock _lock( mutex ); +int FileNode::open(int flags) const { + Lock _lock(mutex); - int res = io->open( flags ); + int res = io->open(flags); return res; } -int FileNode::getAttr(struct stat *stbuf) const -{ - Lock _lock( mutex ); +int FileNode::getAttr(struct stat *stbuf) const { + Lock _lock(mutex); - int res = io->getAttr( stbuf ); + int res = io->getAttr(stbuf); return res; } -off_t FileNode::getSize() const -{ - Lock _lock( mutex ); +off_t FileNode::getSize() const { + Lock _lock(mutex); int res = io->getSize(); return res; } -ssize_t FileNode::read( off_t offset, unsigned char *data, ssize_t size ) const -{ +ssize_t FileNode::read(off_t offset, unsigned char *data, ssize_t size) const { IORequest req; req.offset = offset; req.dataLen = size; req.data = data; - Lock _lock( mutex ); + Lock _lock(mutex); - return io->read( req ); + return io->read(req); } -bool FileNode::write(off_t offset, unsigned char *data, ssize_t size) -{ - VLOG(1) << "FileNode::write offset " << offset - << ", data size " << size; +bool FileNode::write(off_t offset, unsigned char *data, ssize_t size) { + VLOG(1) << "FileNode::write offset " << offset << ", data size " << size; IORequest req; req.offset = offset; req.dataLen = size; req.data = data; - Lock _lock( mutex ); + Lock _lock(mutex); - return io->write( req ); + return io->write(req); } -int FileNode::truncate( off_t size ) -{ - Lock _lock( mutex ); +int FileNode::truncate(off_t size) { + Lock _lock(mutex); - return io->truncate( size ); + return io->truncate(size); } -int FileNode::sync(bool datasync) -{ - Lock _lock( mutex ); +int FileNode::sync(bool datasync) { + Lock _lock(mutex); - int fh = io->open( O_RDONLY ); - if(fh >= 0) - { + int fh = io->open(O_RDONLY); + if (fh >= 0) { int res = -EIO; #ifdef linux - if(datasync) - res = fdatasync( fh ); + if (datasync) + res = fdatasync(fh); else - res = fsync( fh ); + res = fsync(fh); #else // no fdatasync support // TODO: use autoconfig to check for it.. res = fsync(fh); #endif - if(res == -1) - res = -errno; + if (res == -1) res = -errno; return res; } else diff --git a/fs/FileNode.h b/fs/FileNode.h index a4e6633..caebe53 100644 --- a/fs/FileNode.h +++ b/fs/FileNode.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + #ifndef _FileNode_incl_ #define _FileNode_incl_ @@ -36,69 +36,64 @@ class Cipher; class FileIO; class DirNode; -class FileNode -{ -public: - FileNode(DirNode *parent, - const FSConfigPtr &cfg, - const char *plaintextName, - const char *cipherName); - ~FileNode(); +class FileNode { + public: + FileNode(DirNode *parent, const FSConfigPtr &cfg, const char *plaintextName, + const char *cipherName); + ~FileNode(); - const char *plaintextName() const; - const char *cipherName() const; + const char *plaintextName() const; + const char *cipherName() const; - // directory portion of plaintextName - std::string plaintextParent() const; + // directory portion of plaintextName + std::string plaintextParent() const; - // if setIVFirst is true, then the IV is changed before the name is changed - // (default). The reverse is also supported for special cases.. - bool setName( const char *plaintextName, const char *cipherName, - uint64_t iv, bool setIVFirst = true); + // if setIVFirst is true, then the IV is changed before the name is changed + // (default). The reverse is also supported for special cases.. + bool setName(const char *plaintextName, const char *cipherName, uint64_t iv, + bool setIVFirst = true); - // create node - // If uid/gid are not 0, then chown is used change ownership as specified - int mknod(mode_t mode, dev_t rdev, uid_t uid = 0, gid_t gid = 0); + // create node + // If uid/gid are not 0, then chown is used change ownership as specified + int mknod(mode_t mode, dev_t rdev, uid_t uid = 0, gid_t gid = 0); - // Returns < 0 on error (-errno), file descriptor on success. - int open(int flags) const; + // Returns < 0 on error (-errno), file descriptor on success. + int open(int flags) const; - // getAttr returns 0 on success, -errno on failure - int getAttr(struct stat *stbuf) const; - off_t getSize() const; + // getAttr returns 0 on success, -errno on failure + int getAttr(struct stat *stbuf) const; + off_t getSize() const; - ssize_t read(off_t offset, unsigned char *data, ssize_t size) const; - bool write(off_t offset, unsigned char *data, ssize_t size); + ssize_t read(off_t offset, unsigned char *data, ssize_t size) const; + bool write(off_t offset, unsigned char *data, ssize_t size); - // truncate the file to a particular size - int truncate( off_t size ); + // truncate the file to a particular size + int truncate(off_t size); - // datasync or full sync - int sync(bool dataSync); -private: + // datasync or full sync + int sync(bool dataSync); - // doing locking at the FileNode level isn't as efficient as at the - // lowest level of RawFileIO, since that means locks are held longer - // (held during CPU intensive crypto operations!). However it makes it - // easier to avoid any race conditions with operations such as - // truncate() which may result in multiple calls down to the FileIO - // level. - mutable Mutex mutex; + private: + // doing locking at the FileNode level isn't as efficient as at the + // lowest level of RawFileIO, since that means locks are held longer + // (held during CPU intensive crypto operations!). However it makes it + // easier to avoid any race conditions with operations such as + // truncate() which may result in multiple calls down to the FileIO + // level. + mutable Mutex mutex; - FSConfigPtr fsConfig; + FSConfigPtr fsConfig; - shared_ptr io; - std::string _pname; // plaintext name - std::string _cname; // encrypted name - DirNode *parent; - -private: - FileNode(const FileNode &src); - FileNode &operator = (const FileNode &src); + shared_ptr io; + std::string _pname; // plaintext name + std::string _cname; // encrypted name + DirNode *parent; + private: + FileNode(const FileNode &src); + FileNode &operator=(const FileNode &src); }; } // namespace encfs #endif - diff --git a/fs/FileUtils.cpp b/fs/FileUtils.cpp index 40c4195..ada05dd 100644 --- a/fs/FileUtils.cpp +++ b/fs/FileUtils.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -20,9 +20,9 @@ // defines needed for RedHat 7.3... #ifdef linux -#define _XOPEN_SOURCE 500 // make sure pwrite() is pulled in +#define _XOPEN_SOURCE 500 // make sure pwrite() is pulled in #endif -#define _BSD_SOURCE // pick up setenv on RH7.3 +#define _BSD_SOURCE // pick up setenv on RH7.3 #include "fs/encfs.h" #include "fs/fsconfig.pb.h" @@ -80,8 +80,8 @@ static const int DefaultBlockSize = 2048; // use the extpass option, as extpass can return arbitrary length binary data. static const int MaxPassBuf = 2048; -static const int NormalKDFDuration = 500; // 1/2 a second -static const int ParanoiaKDFDuration = 3000; // 3 seconds +static const int NormalKDFDuration = 500; // 1/2 a second +static const int ParanoiaKDFDuration = 3000; // 3 seconds // environment variable names for values encfs stores in the environment when // calling an external password program. @@ -89,171 +89,141 @@ static const char ENCFS_ENV_ROOTDIR[] = "encfs_root"; static const char ENCFS_ENV_STDOUT[] = "encfs_stdout"; static const char ENCFS_ENV_STDERR[] = "encfs_stderr"; -const int V5Latest = 20040813; // fix MACFileIO block size issues +const int V5Latest = 20040813; // fix MACFileIO block size issues const int ProtoSubVersion = 20120902; const char ConfigFileName[] = ".encfs.txt"; -struct ConfigInfo -{ +struct ConfigInfo { ConfigType type; const char *fileName; const char *environmentOverride; - bool (*loadFunc)(const char *fileName, - EncfsConfig &config, ConfigInfo *cfg); + bool (*loadFunc)(const char *fileName, EncfsConfig &config, ConfigInfo *cfg); } ConfigFileMapping[] = { - {Config_V7, ConfigFileName, "ENCFS_CONFIG", readProtoConfig }, - {Config_V6, ".encfs6.xml", "ENCFS6_CONFIG", readV6Config }, - // backward compatible support for older versions - {Config_V5, ".encfs5", "ENCFS5_CONFIG", readV5Config }, - {Config_V4, ".encfs4", NULL, readV4Config }, - // prehistoric - no longer support - {Config_V3, ".encfs3", NULL, NULL }, - {Config_Prehistoric, ".encfs2", NULL, NULL }, - {Config_Prehistoric, ".encfs", NULL, NULL }, - {Config_None, NULL, NULL, NULL } }; + {Config_V7, ConfigFileName, "ENCFS_CONFIG", readProtoConfig}, + {Config_V6, ".encfs6.xml", "ENCFS6_CONFIG", readV6Config}, + // backward compatible support for older versions + {Config_V5, ".encfs5", "ENCFS5_CONFIG", readV5Config}, + {Config_V4, ".encfs4", NULL, readV4Config}, + // prehistoric - no longer support + {Config_V3, ".encfs3", NULL, NULL}, + {Config_Prehistoric, ".encfs2", NULL, NULL}, + {Config_Prehistoric, ".encfs", NULL, NULL}, + {Config_None, NULL, NULL, NULL}}; -EncFS_Root::EncFS_Root() -{ -} +EncFS_Root::EncFS_Root() {} -EncFS_Root::~EncFS_Root() -{ -} +EncFS_Root::~EncFS_Root() {} - -bool fileExists( const char * fileName ) -{ +bool fileExists(const char *fileName) { struct stat buf; - if(!lstat( fileName, &buf )) - { + if (!lstat(fileName, &buf)) { return true; - } else - { + } else { // XXX show perror? return false; } } -bool isDirectory( const char *fileName ) -{ +bool isDirectory(const char *fileName) { struct stat buf; - if( !lstat( fileName, &buf )) - { - return S_ISDIR( buf.st_mode ); - } else - { + if (!lstat(fileName, &buf)) { + return S_ISDIR(buf.st_mode); + } else { return false; } } -bool isAbsolutePath( const char *fileName ) -{ - if(fileName && fileName[0] != '\0' && fileName[0] == '/') +bool isAbsolutePath(const char *fileName) { + if (fileName && fileName[0] != '\0' && fileName[0] == '/') return true; else return false; } -const char *lastPathElement( const char *name ) -{ - const char *loc = strrchr( name, '/' ); +const char *lastPathElement(const char *name) { + const char *loc = strrchr(name, '/'); return loc ? loc + 1 : name; } -std::string parentDirectory( const std::string &path ) -{ - size_t last = path.find_last_of( '/' ); - if(last == string::npos) +std::string parentDirectory(const std::string &path) { + size_t last = path.find_last_of('/'); + if (last == string::npos) return string(""); else return path.substr(0, last); } -bool userAllowMkdir(const char *path, mode_t mode ) -{ - return userAllowMkdir(0, path, mode); +bool userAllowMkdir(const char *path, mode_t mode) { + return userAllowMkdir(0, path, mode); } -bool userAllowMkdir(int promptno, const char *path, mode_t mode ) -{ +bool userAllowMkdir(int promptno, const char *path, mode_t mode) { // TODO: can we internationalize the y/n names? Seems strange to prompt in // their own language but then have to respond 'y' or 'n'. // xgroup(setup) - cerr << autosprintf( _("The directory \"%s\" does not exist. " - "Should it be created? (y,n) "), path ); + cerr << autosprintf(_("The directory \"%s\" does not exist. " + "Should it be created? (y,n) "), + path); char answer[10]; char *res; - switch (promptno) - { - case 1: - cerr << endl << "$PROMPT$ create_root_dir" << endl; - break; - case 2: - cerr << endl << "$PROMPT$ create_mount_point" << endl; - break; - default: - break; + switch (promptno) { + case 1: + cerr << endl << "$PROMPT$ create_root_dir" << endl; + break; + case 2: + cerr << endl << "$PROMPT$ create_mount_point" << endl; + break; + default: + break; } - res = fgets( answer, sizeof(answer), stdin ); + res = fgets(answer, sizeof(answer), stdin); - if(res != 0 && toupper(answer[0]) == 'Y') - { - int result = mkdir( path, mode ); - if(result < 0) - { - perror( _("Unable to create directory: ") ); + if (res != 0 && toupper(answer[0]) == 'Y') { + int result = mkdir(path, mode); + if (result < 0) { + perror(_("Unable to create directory: ")); return false; } else return true; - } else - { + } else { // Directory not created, by user request cerr << _("Directory not created.") << "\n"; return false; } } -ConfigType readConfig_load( ConfigInfo *nm, const char *path, - EncfsConfig &config ) -{ - if( nm->loadFunc ) - { - try - { - if( (*nm->loadFunc)( path, config, nm )) - return nm->type; - } catch( Error &err ) - { +ConfigType readConfig_load(ConfigInfo *nm, const char *path, + EncfsConfig &config) { + if (nm->loadFunc) { + try { + if ((*nm->loadFunc)(path, config, nm)) return nm->type; + } + catch (Error &err) { LOG(WARNING) << "readConfig failed: " << err.what(); } LOG(ERROR) << "Found config file " << path << ", but failed to load"; return Config_None; - } else - { + } else { // No load function - must be an unsupported type.. return Config_None; } } -ConfigType readConfig( const string &rootDir, EncfsConfig &config ) -{ +ConfigType readConfig(const string &rootDir, EncfsConfig &config) { ConfigInfo *nm = ConfigFileMapping; - while(nm->fileName) - { + while (nm->fileName) { // allow environment variable to override default config path - if( nm->environmentOverride != NULL ) - { - char *envFile = getenv( nm->environmentOverride ); - if( envFile != NULL ) - return readConfig_load( nm, envFile, config ); + if (nm->environmentOverride != NULL) { + char *envFile = getenv(nm->environmentOverride); + if (envFile != NULL) return readConfig_load(nm, envFile, config); } // the standard place to look is in the root directory string path = rootDir + nm->fileName; - if( fileExists( path.c_str() ) ) - return readConfig_load( nm, path.c_str(), config); + if (fileExists(path.c_str())) + return readConfig_load(nm, path.c_str(), config); ++nm; } @@ -262,14 +232,11 @@ ConfigType readConfig( const string &rootDir, EncfsConfig &config ) } // Read a boost::serialization config file using an Xml reader.. -bool readV6Config( const char *configFile, - EncfsConfig &cfg, ConfigInfo *info) -{ +bool readV6Config(const char *configFile, EncfsConfig &cfg, ConfigInfo *info) { (void)info; XmlReader rdr; - if (!rdr.load(configFile)) - { + if (!rdr.load(configFile)) { LOG(ERROR) << "Failed to load config file " << configFile; return false; } @@ -291,25 +258,19 @@ bool readV6Config( const char *configFile, return false; } - // version numbering was complicated by boost::archive - if (version == 20 || version >= 20100713) - { + // version numbering was complicated by boost::archive + if (version == 20 || version >= 20100713) { VLOG(1) << "found new serialization format"; cfg.set_revision(version); - } else if (version == 26800) - { + } else if (version == 26800) { VLOG(1) << "found 20080816 version"; cfg.set_revision(20080816); - } else if (version == 26797) - { + } else if (version == 26797) { VLOG(1) << "found 20080813"; cfg.set_revision(20080813); - } else if (version < V5Latest) - { - LOG(ERROR) << "Invalid version " << version - << " - please fix config file"; - } else - { + } else if (version < V5Latest) { + LOG(ERROR) << "Invalid version " << version << " - please fix config file"; + } else { LOG(INFO) << "Boost <= 1.41 compatibility mode"; cfg.set_revision(version); } @@ -346,13 +307,12 @@ bool readV6Config( const char *configFile, config->readB64("encodedKeyData", key, encodedSize); encryptedKey->set_ciphertext(key, encodedSize); delete[] key; - + int keySize; config->read("keySize", &keySize); - encryptedKey->set_size(keySize / 8); // save as size in bytes + encryptedKey->set_size(keySize / 8); // save as size in bytes - if(cfg.revision() >= 20080816) - { + if (cfg.revision() >= 20080816) { int saltLen; config->read("saltLen", &saltLen); unsigned char *salt = new unsigned char[saltLen]; @@ -365,8 +325,7 @@ bool readV6Config( const char *configFile, config->read("desiredKDFDuration", &desiredKDFDuration); encryptedKey->set_kdf_iterations(kdfIterations); encryptedKey->set_kdf_duration(desiredKDFDuration); - } else - { + } else { encryptedKey->clear_salt(); encryptedKey->set_kdf_iterations(16); encryptedKey->clear_kdf_duration(); @@ -376,31 +335,27 @@ bool readV6Config( const char *configFile, } // Read a v5 archive, which is a proprietary binary format. -bool readV5Config( const char *configFile, - EncfsConfig &config, ConfigInfo *) -{ +bool readV5Config(const char *configFile, EncfsConfig &config, ConfigInfo *) { bool ok = false; // use Config to parse the file and query it.. ConfigReader cfgRdr; - if(cfgRdr.load( configFile )) - { - try - { + if (cfgRdr.load(configFile)) { + try { config.set_revision(cfgRdr["subVersion"].readInt(0)); - if(config.revision() > V5Latest) - { + if (config.revision() > V5Latest) { /* config file specifies a version outside our supported range.. */ - LOG(ERROR) << "Config subversion " << config.revision() - << " found, but this version of encfs only supports up to version " - << V5Latest; + LOG(ERROR) + << "Config subversion " << config.revision() + << " found, but this version of encfs only supports up to version " + << V5Latest; return false; } - if( config.revision() < V5Latest ) - { - LOG(ERROR) << "This version of EncFS doesn't support " - << "filesystems created with EncFS releases before 2004-08-13"; + if (config.revision() < V5Latest) { + LOG(ERROR) + << "This version of EncFS doesn't support " + << "filesystems created with EncFS releases before 2004-08-13"; return false; } @@ -418,17 +373,17 @@ bool readV5Config( const char *configFile, encryptedKey->set_size(keySize / 8); cfgRdr["keyData"] >> (*encryptedKey->mutable_ciphertext()); - config.set_unique_iv( cfgRdr["uniqueIV"].readBool( false ) ); - config.set_chained_iv( cfgRdr["chainedIV"].readBool( false ) ); - config.set_external_iv( cfgRdr["externalIV"].readBool( false ) ); - config.set_block_mac_bytes( cfgRdr["blockMACBytes"].readInt(0) ); - config.set_block_mac_rand_bytes( cfgRdr["blockMACRandBytes"].readInt(0) ); + config.set_unique_iv(cfgRdr["uniqueIV"].readBool(false)); + config.set_chained_iv(cfgRdr["chainedIV"].readBool(false)); + config.set_external_iv(cfgRdr["externalIV"].readBool(false)); + config.set_block_mac_bytes(cfgRdr["blockMACBytes"].readInt(0)); + config.set_block_mac_rand_bytes(cfgRdr["blockMACRandBytes"].readInt(0)); ok = true; - } catch( Error &err) - { - LOG(WARNING) << "Error parsing data in config file " << configFile - << "; " << err.what(); + } + catch (Error &err) { + LOG(WARNING) << "Error parsing data in config file " << configFile << "; " + << err.what(); ok = false; } } @@ -436,17 +391,13 @@ bool readV5Config( const char *configFile, return ok; } -bool readV4Config( const char *configFile, - EncfsConfig &config, ConfigInfo *) -{ +bool readV4Config(const char *configFile, EncfsConfig &config, ConfigInfo *) { bool ok = false; // use Config to parse the file and query it.. ConfigReader cfgRdr; - if(cfgRdr.load( configFile )) - { - try - { + if (cfgRdr.load(configFile)) { + try { cfgRdr["cipher"] >> (*config.mutable_cipher()); int blockSize; cfgRdr["blockSize"] >> blockSize; @@ -456,14 +407,15 @@ bool readV4Config( const char *configFile, cfgRdr["keyData"] >> (*key->mutable_ciphertext()); // fill in default for V4 - config.mutable_naming()->MergeFrom( makeInterface("nameio/stream", 1, 0, 0) ); - config.set_creator( "EncFS 1.0.x" ); + config.mutable_naming()->MergeFrom( + makeInterface("nameio/stream", 1, 0, 0)); + config.set_creator("EncFS 1.0.x"); ok = true; - } catch( Error &err) - { - LOG(WARNING) << "Error parsing config file " << configFile - << ": " << err.what(); + } + catch (Error &err) { + LOG(WARNING) << "Error parsing config file " << configFile << ": " + << err.what(); ok = false; } } @@ -471,44 +423,38 @@ bool readV4Config( const char *configFile, return ok; } -bool writeTextConfig( const char *fileName, const EncfsConfig &cfg ) -{ - int fd = ::open( fileName, O_RDWR | O_CREAT, 0640 ); - if (fd < 0) - { +bool writeTextConfig(const char *fileName, const EncfsConfig &cfg) { + int fd = ::open(fileName, O_RDWR | O_CREAT, 0640); + if (fd < 0) { LOG(ERROR) << "Unable to open or create file " << fileName; return false; } - google::protobuf::io::FileOutputStream fos( fd ); - google::protobuf::TextFormat::Print( cfg, &fos ); + google::protobuf::io::FileOutputStream fos(fd); + google::protobuf::TextFormat::Print(cfg, &fos); fos.Close(); return true; } -bool saveConfig( const string &rootDir, const EncfsConfig &config ) -{ +bool saveConfig(const string &rootDir, const EncfsConfig &config) { bool ok = false; ConfigInfo *nm = ConfigFileMapping; - + // TODO(vgough): remove old config after saving a new one? string path = rootDir + ConfigFileName; - if( nm->environmentOverride != NULL ) - { + if (nm->environmentOverride != NULL) { // use environment file if specified.. - const char *envFile = getenv( nm->environmentOverride ); - if( envFile != NULL ) - path.assign( envFile ); + const char *envFile = getenv(nm->environmentOverride); + if (envFile != NULL) path.assign(envFile); } - try - { - const_cast(config).set_writer("EncFS " VERSION ); - ok = writeTextConfig( path.c_str(), config ); - } catch( Error &err ) - { + try { + const_cast(config).set_writer("EncFS " VERSION); + ok = writeTextConfig(path.c_str(), config); + } + catch (Error &err) { LOG(WARNING) << "saveConfig failed: " << err.what(); ok = false; } @@ -516,31 +462,24 @@ bool saveConfig( const string &rootDir, const EncfsConfig &config ) return ok; } -bool readProtoConfig( const char *fileName, EncfsConfig &config, - struct ConfigInfo *) -{ - int fd = ::open( fileName, O_RDONLY, 0640 ); - if (fd < 0) - { +bool readProtoConfig(const char *fileName, EncfsConfig &config, + struct ConfigInfo *) { + int fd = ::open(fileName, O_RDONLY, 0640); + if (fd < 0) { LOG(ERROR) << "Unable to open file " << fileName; return false; } - google::protobuf::io::FileInputStream fis( fd ); - google::protobuf::TextFormat::Parse( &fis, &config ); + google::protobuf::io::FileInputStream fis(fd); + google::protobuf::TextFormat::Parse(&fis, &config); return true; } -static -CipherV1::CipherAlgorithm findCipherAlgorithm(const char *name, - int keySize ) -{ - for (auto &it : CipherV1::GetAlgorithmList()) - { - if( !strcmp( name, it.name.c_str() ) - && it.keyLength.allowed( keySize )) - { +static CipherV1::CipherAlgorithm findCipherAlgorithm(const char *name, + int keySize) { + for (auto &it : CipherV1::GetAlgorithmList()) { + if (!strcmp(name, it.name.c_str()) && it.keyLength.allowed(keySize)) { return it; } } @@ -549,112 +488,95 @@ CipherV1::CipherAlgorithm findCipherAlgorithm(const char *name, return result; } -static -CipherV1::CipherAlgorithm selectCipherAlgorithm() -{ - for(;;) - { +static CipherV1::CipherAlgorithm selectCipherAlgorithm() { + for (;;) { // figure out what cipher they want to use.. // xgroup(setup) cout << _("The following cipher algorithms are available:") << "\n"; int optNum = 0; auto algorithms = CipherV1::GetAlgorithmList(); - for (auto &it : algorithms) - { - cout << ++optNum << ". " << it.name - << " : " << gettext(it.description.c_str()) << "\n"; - if(it.keyLength.min() == it.keyLength.max()) - { + for (auto &it : algorithms) { + cout << ++optNum << ". " << it.name << " : " + << gettext(it.description.c_str()) << "\n"; + if (it.keyLength.min() == it.keyLength.max()) { // shown after algorithm name and description. // xgroup(setup) - cout << autosprintf(_(" -- key length %i bits") - , it.keyLength.min()) << "\n"; - } else - { + cout << autosprintf(_(" -- key length %i bits"), it.keyLength.min()) + << "\n"; + } else { cout << autosprintf( - // shown after algorithm name and description. - // xgroup(setup) - _(" -- Supports key lengths of %i to %i bits"), - it.keyLength.min(), it.keyLength.max()) << "\n"; + // shown after algorithm name and description. + // xgroup(setup) + _(" -- Supports key lengths of %i to %i bits"), + it.keyLength.min(), it.keyLength.max()) << "\n"; } - if(it.blockSize.min() == it.blockSize.max()) - { + if (it.blockSize.min() == it.blockSize.max()) { cout << autosprintf( - // shown after algorithm name and description. - // xgroup(setup) - _(" -- block size %i bytes"), it.blockSize.min()) - << "\n"; - } else - { + // shown after algorithm name and description. + // xgroup(setup) + _(" -- block size %i bytes"), it.blockSize.min()) << "\n"; + } else { cout << autosprintf( - // shown after algorithm name and description. - // xgroup(setup) - _(" -- Supports block sizes of %i to %i bytes"), - it.blockSize.min(), it.blockSize.max()) << "\n"; + // shown after algorithm name and description. + // xgroup(setup) + _(" -- Supports block sizes of %i to %i bytes"), + it.blockSize.min(), it.blockSize.max()) << "\n"; } } // xgroup(setup) cout << "\n" << _("Enter the number corresponding to your choice: "); char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); - int cipherNum = (res == 0 ? 0 : atoi( answer )); + char *res = fgets(answer, sizeof(answer), stdin); + int cipherNum = (res == 0 ? 0 : atoi(answer)); cout << "\n"; - if( cipherNum < 1 || cipherNum > (int)algorithms.size() ) - { + if (cipherNum < 1 || cipherNum > (int)algorithms.size()) { cerr << _("Invalid selection.") << "\n"; continue; } CipherV1::CipherAlgorithm alg; - for (auto &it : algorithms) - { - if (!--cipherNum) - { + for (auto &it : algorithms) { + if (!--cipherNum) { alg = it; break; } } // xgroup(setup) - cout << autosprintf(_("Selected algorithm \"%s\""), alg.name.c_str()) - << "\n\n"; + cout << autosprintf(_("Selected algorithm \"%s\""), alg.name.c_str()) + << "\n\n"; return alg; } } -static -Interface selectNameCoding(const CipherV1::CipherAlgorithm &alg) -{ - for(;;) - { +static Interface selectNameCoding(const CipherV1::CipherAlgorithm &alg) { + for (;;) { // figure out what cipher they want to use.. // xgroup(setup) cout << _("The following filename encoding algorithms are available:") - << "\n"; + << "\n"; NameIO::AlgorithmList algorithms = NameIO::GetAlgorithmList(); NameIO::AlgorithmList::const_iterator it; int optNum = 1; map algMap; - for(it = algorithms.begin(); it != algorithms.end(); ++it) - { - cout << optNum << ". " << it->name - << " : " << gettext(it->description.c_str()) << "\n"; + for (it = algorithms.begin(); it != algorithms.end(); ++it) { + cout << optNum << ". " << it->name << " : " + << gettext(it->description.c_str()) << "\n"; algMap[optNum++] = it; } // xgroup(setup) cout << "\n" << _("Enter the number corresponding to your choice: "); char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); - int algNum = (res == 0 ? 0 : atoi( answer )); + char *res = fgets(answer, sizeof(answer), stdin); + int algNum = (res == 0 ? 0 : atoi(answer)); cout << "\n"; - if( algNum < 1 || algNum >= optNum ) - { + if (algNum < 1 || algNum >= optNum) { cerr << _("Invalid selection.") << "\n"; continue; } @@ -662,61 +584,55 @@ Interface selectNameCoding(const CipherV1::CipherAlgorithm &alg) it = algMap[algNum]; // xgroup(setup) - cout << autosprintf(_("Selected algorithm \"%s\""), it->name.c_str()) - << "\"\n\n"; + cout << autosprintf(_("Selected algorithm \"%s\""), it->name.c_str()) + << "\"\n\n"; return it->iface; } } static int selectKDFDuration() { - cout << autosprintf(_("Select desired KDF duration in milliseconds.\n" - "The default is 500 (half a second): ")); + cout << autosprintf( + _("Select desired KDF duration in milliseconds.\n" + "The default is 500 (half a second): ")); char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); - int duration = (res == 0 ? 0 : atoi( answer )); + char *res = fgets(answer, sizeof(answer), stdin); + int duration = (res == 0 ? 0 : atoi(answer)); cout << "\n"; return duration; } -static -int selectKeySize( const CipherV1::CipherAlgorithm &alg ) -{ - if(alg.keyLength.min() == alg.keyLength.max()) - { - cout << autosprintf(_("Using key size of %i bits"), - alg.keyLength.min()) << "\n"; +static int selectKeySize(const CipherV1::CipherAlgorithm &alg) { + if (alg.keyLength.min() == alg.keyLength.max()) { + cout << autosprintf(_("Using key size of %i bits"), alg.keyLength.min()) + << "\n"; return alg.keyLength.min(); } - cout << autosprintf( - // xgroup(setup) - _("Please select a key size in bits. The cipher you have chosen\n" - "supports sizes from %i to %i bits in increments of %i bits.\n" - "For example: "), alg.keyLength.min(), alg.keyLength.max(), - alg.keyLength.inc()) << "\n"; + cout + << autosprintf( + // xgroup(setup) + _("Please select a key size in bits. The cipher you have chosen\n" + "supports sizes from %i to %i bits in increments of %i bits.\n" + "For example: "), + alg.keyLength.min(), alg.keyLength.max(), alg.keyLength.inc()) + << "\n"; - int numAvail = (alg.keyLength.max() - alg.keyLength.min()) - / alg.keyLength.inc(); + int numAvail = + (alg.keyLength.max() - alg.keyLength.min()) / alg.keyLength.inc(); - if(numAvail < 5) - { + if (numAvail < 5) { // show them all - for(int i=0; i<=numAvail; ++i) - { - if(i) - cout << ", "; + for (int i = 0; i <= numAvail; ++i) { + if (i) cout << ", "; cout << alg.keyLength.min() + i * alg.keyLength.inc(); } - } else - { + } else { // partial - for(int i=0; i<3; ++i) - { - if(i) - cout << ", "; + for (int i = 0; i < 3; ++i) { + if (i) cout << ", "; cout << alg.keyLength.min() + i * alg.keyLength.inc(); } cout << " ... " << alg.keyLength.max() - alg.keyLength.inc(); @@ -726,11 +642,11 @@ int selectKeySize( const CipherV1::CipherAlgorithm &alg ) cout << "\n" << _("Selected key size: "); char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); - int keySize = (res == 0 ? 0 : atoi( answer )); + char *res = fgets(answer, sizeof(answer), stdin); + int keySize = (res == 0 ? 0 : atoi(answer)); cout << "\n"; - keySize = alg.keyLength.closest( keySize ); + keySize = alg.keyLength.closest(keySize); // xgroup(setup) cout << autosprintf(_("Using key size of %i bits"), keySize) << "\n\n"; @@ -738,66 +654,58 @@ int selectKeySize( const CipherV1::CipherAlgorithm &alg ) return keySize; } -static -int selectBlockSize( const CipherV1::CipherAlgorithm &alg ) -{ - if(alg.blockSize.min() == alg.blockSize.max()) - { +static int selectBlockSize(const CipherV1::CipherAlgorithm &alg) { + if (alg.blockSize.min() == alg.blockSize.max()) { cout << autosprintf( - // xgroup(setup) - _("Using filesystem block size of %i bytes"), - alg.blockSize.min()) << "\n"; + // xgroup(setup) + _("Using filesystem block size of %i bytes"), + alg.blockSize.min()) << "\n"; return alg.blockSize.min(); } cout << autosprintf( - // xgroup(setup) - _("Select a block size in bytes. The cipher you have chosen\n" - "supports sizes from %i to %i bytes in increments of %i.\n" - "Or just hit enter for the default (%i bytes)\n"), - alg.blockSize.min(), alg.blockSize.max(), alg.blockSize.inc(), - DefaultBlockSize); + // xgroup(setup) + _("Select a block size in bytes. The cipher you have chosen\n" + "supports sizes from %i to %i bytes in increments of %i.\n" + "Or just hit enter for the default (%i bytes)\n"), + alg.blockSize.min(), alg.blockSize.max(), alg.blockSize.inc(), + DefaultBlockSize); // xgroup(setup) cout << "\n" << _("filesystem block size: "); int blockSize = DefaultBlockSize; char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); + char *res = fgets(answer, sizeof(answer), stdin); cout << "\n"; - if( res != 0 && atoi( answer ) >= alg.blockSize.min() ) - blockSize = atoi( answer ); + if (res != 0 && atoi(answer) >= alg.blockSize.min()) blockSize = atoi(answer); - blockSize = alg.blockSize.closest( blockSize ); + blockSize = alg.blockSize.closest(blockSize); // xgroup(setup) - cout << autosprintf(_("Using filesystem block size of %i bytes"), - blockSize) << "\n\n"; + cout << autosprintf(_("Using filesystem block size of %i bytes"), blockSize) + << "\n\n"; return blockSize; } -static -bool boolDefaultNo(const char *prompt) -{ +static bool boolDefaultNo(const char *prompt) { cout << prompt << "\n"; cout << _("The default here is No.\n" - "Any response that does not begin with 'y' will mean No: "); + "Any response that does not begin with 'y' will mean No: "); char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); + char *res = fgets(answer, sizeof(answer), stdin); cout << "\n"; - if(res != 0 && tolower(answer[0]) == 'y') + if (res != 0 && tolower(answer[0]) == 'y') return true; else return false; } -static -void selectBlockMAC(int *macBytes, int *macRandBytes) -{ +static void selectBlockMAC(int *macBytes, int *macRandBytes) { // xgroup(setup) bool addMAC = boolDefaultNo( _("Enable block authentication code headers\n" @@ -806,54 +714,48 @@ void selectBlockMAC(int *macBytes, int *macRandBytes) "performance but it also means [almost] any modifications or errors\n" "within a block will be caught and will cause a read error.")); - if(addMAC) + if (addMAC) *macBytes = 8; else *macBytes = 0; // xgroup(setup) cout << _("Add random bytes to each block header?\n" - "This adds a performance penalty, but ensures that blocks\n" - "have different authentication codes. Note that you can\n" - "have the same benefits by enabling per-file initialization\n" - "vectors, which does not come with as great of performance\n" - "penalty. \n" - "Select a number of bytes, from 0 (no random bytes) to 8: "); + "This adds a performance penalty, but ensures that blocks\n" + "have different authentication codes. Note that you can\n" + "have the same benefits by enabling per-file initialization\n" + "vectors, which does not come with as great of performance\n" + "penalty. \n" + "Select a number of bytes, from 0 (no random bytes) to 8: "); char answer[10]; int randSize = 0; - char *res = fgets( answer, sizeof(answer), stdin ); + char *res = fgets(answer, sizeof(answer), stdin); cout << "\n"; - randSize = (res == 0 ? 0 : atoi( answer )); - if(randSize < 0) - randSize = 0; - if(randSize > 8) - randSize = 8; + randSize = (res == 0 ? 0 : atoi(answer)); + if (randSize < 0) randSize = 0; + if (randSize > 8) randSize = 8; *macRandBytes = randSize; } -static -bool boolDefaultYes(const char *prompt) -{ +static bool boolDefaultYes(const char *prompt) { cout << prompt << "\n"; cout << _("The default here is Yes.\n" - "Any response that does not begin with 'n' will mean Yes: "); + "Any response that does not begin with 'n' will mean Yes: "); char answer[10]; - char *res = fgets( answer, sizeof(answer), stdin ); + char *res = fgets(answer, sizeof(answer), stdin); cout << "\n"; - if(res != 0 && tolower(answer[0]) == 'n') + if (res != 0 && tolower(answer[0]) == 'n') return false; else return true; } -static -bool selectUniqueIV() -{ +static bool selectUniqueIV() { // xgroup(setup) return boolDefaultYes( _("Enable per-file initialization vectors?\n" @@ -862,9 +764,7 @@ bool selectUniqueIV() "which rely on block-aligned file io for performance.")); } -static -bool selectChainedIV() -{ +static bool selectChainedIV() { // xgroup(setup) return boolDefaultYes( _("Enable filename initialization vector chaining?\n" @@ -872,9 +772,7 @@ bool selectChainedIV() "rather than encoding each path element individually.")); } -static -bool selectExternalChainedIV() -{ +static bool selectExternalChainedIV() { // xgroup(setup) return boolDefaultNo( _("Enable filename to IV header chaining?\n" @@ -885,18 +783,14 @@ bool selectExternalChainedIV() "in the filesystem.")); } -static -bool selectZeroBlockPassThrough() -{ +static bool selectZeroBlockPassThrough() { // xgroup(setup) return boolDefaultYes( _("Enable file-hole pass-through?\n" "This avoids writing encrypted blocks when file holes are created.")); } -RootPtr createConfig( EncFS_Context *ctx, - const shared_ptr &opts ) -{ +RootPtr createConfig(EncFS_Context *ctx, const shared_ptr &opts) { const std::string rootDir = opts->rootDir; bool enableIdleTracking = opts->idleTracking; bool forceDecode = opts->forceDecode; @@ -914,19 +808,17 @@ RootPtr createConfig( EncFS_Context *ctx, cout << _("Creating new encrypted volume.") << endl; char answer[10] = {0}; - if(configMode == Config_Prompt) - { + if (configMode == Config_Prompt) { // xgroup(setup) cout << _("Please choose from one of the following options:\n" - " enter \"x\" for expert configuration mode,\n" - " enter \"p\" for pre-configured paranoia mode,\n" - " anything else, or an empty line will select standard mode.\n" - "?> "); + " enter \"x\" for expert configuration mode,\n" + " enter \"p\" for pre-configured paranoia mode,\n" + " anything else, or an empty line will select standard mode.\n" + "?> "); - if (annotate) - cerr << "$PROMPT$ config_option" << endl; + if (annotate) cerr << "$PROMPT$ config_option" << endl; - char *res = fgets( answer, sizeof(answer), stdin ); + char *res = fgets(answer, sizeof(answer), stdin); (void)res; cout << "\n"; } @@ -943,8 +835,7 @@ RootPtr createConfig( EncFS_Context *ctx, bool allowHoles = true; long desiredKDFDuration = NormalKDFDuration; - if (reverseEncryption) - { + if (reverseEncryption) { uniqueIV = false; chainedIV = false; externalIV = false; @@ -952,10 +843,8 @@ RootPtr createConfig( EncFS_Context *ctx, blockMACRandBytes = 0; } - if(configMode == Config_Paranoia || answer[0] == 'p') - { - if (reverseEncryption) - { + if (configMode == Config_Paranoia || answer[0] == 'p') { + if (reverseEncryption) { LOG(ERROR) << "Paranoia configuration not supported for --reverse"; return rootInfo; } @@ -972,13 +861,12 @@ RootPtr createConfig( EncFS_Context *ctx, alg = findCipherAlgorithm("AES", keySize); nameIOIface = BlockNameIO::CurrentInterface(); blockMACBytes = 8; - blockMACRandBytes = 0; // using uniqueIV, so this isn't necessary + blockMACRandBytes = 0; // using uniqueIV, so this isn't necessary uniqueIV = true; chainedIV = true; externalIV = true; desiredKDFDuration = ParanoiaKDFDuration; - } else if(configMode == Config_Standard || answer[0] != 'x') - { + } else if (configMode == Config_Standard || answer[0] != 'x') { // xgroup(setup) cout << _("Standard configuration selected.") << "\n"; // AES w/ 192 bit key, block name encoding, per-file initialization @@ -990,27 +878,21 @@ RootPtr createConfig( EncFS_Context *ctx, externalIV = false; nameIOIface = BlockNameIO::CurrentInterface(); - if (reverseEncryption) - { - cout << _("--reverse specified, not using unique/chained IV") - << "\n"; - } else - { + if (reverseEncryption) { + cout << _("--reverse specified, not using unique/chained IV") << "\n"; + } else { uniqueIV = true; chainedIV = true; } } - if(answer[0] == 'x' || alg.name.empty()) - { - if(answer[0] != 'x') - { + if (answer[0] == 'x' || alg.name.empty()) { + if (answer[0] != 'x') { // xgroup(setup) cout << _("Sorry, unable to locate cipher for predefined " - "configuration...\n" - "Falling through to Manual configuration mode."); - } else - { + "configuration...\n" + "Falling through to Manual configuration mode."); + } else { // xgroup(setup) cout << _("Manual configuration mode selected."); } @@ -1018,24 +900,21 @@ RootPtr createConfig( EncFS_Context *ctx, // query user for settings.. alg = selectCipherAlgorithm(); - keySize = selectKeySize( alg ); - blockSize = selectBlockSize( alg ); - nameIOIface = selectNameCoding( alg ); - if (reverseEncryption) - { + keySize = selectKeySize(alg); + blockSize = selectBlockSize(alg); + nameIOIface = selectNameCoding(alg); + if (reverseEncryption) { cout << _("--reverse specified, not using unique/chained IV") << "\n"; - } else - { + } else { chainedIV = selectChainedIV(); uniqueIV = selectUniqueIV(); - if(chainedIV && uniqueIV) + if (chainedIV && uniqueIV) externalIV = selectExternalChainedIV(); - else - { + else { // xgroup(setup) cout << _("External chained IV disabled, as both 'IV chaining'\n" - "and 'unique IV' features are required for this option.") - << "\n"; + "and 'unique IV' features are required for this option.") + << "\n"; externalIV = false; } selectBlockMAC(&blockMACBytes, &blockMACRandBytes); @@ -1044,112 +923,102 @@ RootPtr createConfig( EncFS_Context *ctx, desiredKDFDuration = selectKDFDuration(); } - shared_ptr cipher = CipherV1::New( alg.iface, keySize ); - if(!cipher) - { - LOG(ERROR) << "Unable to instanciate cipher " << alg.name - << ", key size " << keySize << ", block size " << blockSize; + shared_ptr cipher = CipherV1::New(alg.iface, keySize); + if (!cipher) { + LOG(ERROR) << "Unable to instanciate cipher " << alg.name << ", key size " + << keySize << ", block size " << blockSize; return rootInfo; - } else - { - VLOG(1) << "Using cipher " << alg.name - << ", key size " << keySize << ", block size " << blockSize; + } else { + VLOG(1) << "Using cipher " << alg.name << ", key size " << keySize + << ", block size " << blockSize; } EncfsConfig config; - config.mutable_cipher()->MergeFrom( cipher->interface() ); - config.set_block_size( blockSize ); - config.mutable_naming()->MergeFrom( nameIOIface ); - config.set_creator( "EncFS " VERSION ); - config.set_revision( ProtoSubVersion ); - config.set_block_mac_bytes( blockMACBytes ); - config.set_block_mac_rand_bytes( blockMACRandBytes ); - config.set_unique_iv( uniqueIV ); - config.set_chained_iv( chainedIV ); - config.set_external_iv( externalIV ); - config.set_allow_holes( allowHoles ); + config.mutable_cipher()->MergeFrom(cipher->interface()); + config.set_block_size(blockSize); + config.mutable_naming()->MergeFrom(nameIOIface); + config.set_creator("EncFS " VERSION); + config.set_revision(ProtoSubVersion); + config.set_block_mac_bytes(blockMACBytes); + config.set_block_mac_rand_bytes(blockMACRandBytes); + config.set_unique_iv(uniqueIV); + config.set_chained_iv(chainedIV); + config.set_external_iv(externalIV); + config.set_allow_holes(allowHoles); EncryptedKey *key = config.mutable_key(); key->clear_salt(); - key->clear_kdf_iterations(); // filled in by keying function - key->set_kdf_duration( desiredKDFDuration ); + key->clear_kdf_iterations(); // filled in by keying function + key->set_kdf_duration(desiredKDFDuration); key->set_size(keySize / 8); cout << "\n"; // xgroup(setup) cout << _("Configuration finished. The filesystem to be created has\n" - "the following properties:") << endl; - showFSInfo( config ); + "the following properties:") << endl; + showFSInfo(config); - if( config.external_iv() ) - { - cout << - _("-------------------------- WARNING --------------------------\n") - << - _("The external initialization-vector chaining option has been\n" - "enabled. This option disables the use of hard links on the\n" - "filesystem. Without hard links, some programs may not work.\n" - "The programs 'mutt' and 'procmail' are known to fail. For\n" - "more information, please see the encfs mailing list.\n" - "If you would like to choose another configuration setting,\n" - "please press CTRL-C now to abort and start over.") << endl; + if (config.external_iv()) { + cout << _("-------------------------- WARNING --------------------------\n") + << _("The external initialization-vector chaining option has been\n" + "enabled. This option disables the use of hard links on the\n" + "filesystem. Without hard links, some programs may not work.\n" + "The programs 'mutt' and 'procmail' are known to fail. For\n" + "more information, please see the encfs mailing list.\n" + "If you would like to choose another configuration setting,\n" + "please press CTRL-C now to abort and start over.") << endl; cout << endl; } // xgroup(setup) cout << _("Now you will need to enter a password for your filesystem.\n" - "You will need to remember this password, as there is absolutely\n" - "no recovery mechanism. However, the password can be changed\n" - "later using encfsctl.\n\n"); + "You will need to remember this password, as there is absolutely\n" + "no recovery mechanism. However, the password can be changed\n" + "later using encfsctl.\n\n"); int encodedKeySize = cipher->encodedKeySize(); - unsigned char *encodedKey = new unsigned char[ encodedKeySize ]; + unsigned char *encodedKey = new unsigned char[encodedKeySize]; CipherKey volumeKey = cipher->newRandomKey(); // get user key and use it to encode volume key CipherKey userKey; VLOG(1) << "useStdin: " << useStdin; - if(useStdin) - { - if (annotate) - cerr << "$PROMPT$ new_passwd" << endl; + if (useStdin) { + if (annotate) cerr << "$PROMPT$ new_passwd" << endl; } - userKey = getNewUserKey( config, useStdin, passwordProgram, rootDir ); + userKey = getNewUserKey(config, useStdin, passwordProgram, rootDir); - cipher->setKey( userKey ); - cipher->writeKey( volumeKey, encodedKey ); + cipher->setKey(userKey); + cipher->writeKey(volumeKey, encodedKey); userKey.reset(); key->set_ciphertext(encodedKey, encodedKeySize); delete[] encodedKey; - if(!volumeKey.valid()) - { + if (!volumeKey.valid()) { LOG(ERROR) << "Failure generating new volume key! " - << "Please report this error."; + << "Please report this error."; return rootInfo; } - cipher->setKey( volumeKey ); - if(!saveConfig( rootDir, config )) - return rootInfo; + cipher->setKey(volumeKey); + if (!saveConfig(rootDir, config)) return rootInfo; // fill in config struct - shared_ptr nameCoder = NameIO::New( config.naming(), cipher ); - if(!nameCoder) - { + shared_ptr nameCoder = NameIO::New(config.naming(), cipher); + if (!nameCoder) { LOG(WARNING) << "Name coding interface not supported"; - cout << _("The filename encoding interface requested is not available") - << endl; + cout << _("The filename encoding interface requested is not available") + << endl; return rootInfo; } - nameCoder->setChainedNameIV( config.chained_iv() ); - nameCoder->setReverseEncryption( reverseEncryption ); + nameCoder->setChainedNameIV(config.chained_iv()); + nameCoder->setReverseEncryption(reverseEncryption); - FSConfigPtr fsConfig (new FSConfig); + FSConfigPtr fsConfig(new FSConfig); fsConfig->cipher = cipher; fsConfig->key = volumeKey; fsConfig->nameCoding = nameCoder; @@ -1159,37 +1028,33 @@ RootPtr createConfig( EncFS_Context *ctx, fsConfig->idleTracking = enableIdleTracking; fsConfig->opts = opts; - rootInfo = RootPtr( new EncFS_Root ); + rootInfo = RootPtr(new EncFS_Root); rootInfo->cipher = cipher; rootInfo->volumeKey = volumeKey; - rootInfo->root = shared_ptr( - new DirNode( ctx, rootDir, fsConfig )); + rootInfo->root = shared_ptr(new DirNode(ctx, rootDir, fsConfig)); return rootInfo; } -void showFSInfo( const EncfsConfig &config ) -{ - shared_ptr cipher = CipherV1::New( config.cipher(), - config.key().size() ); +void showFSInfo(const EncfsConfig &config) { + shared_ptr cipher = + CipherV1::New(config.cipher(), config.key().size()); { cout << autosprintf( - // xgroup(diag) - _("Filesystem cipher: \"%s\", version %i:%i:%i"), - config.cipher().name().c_str(), config.cipher().major(), - config.cipher().minor(), config.cipher().age()); + // xgroup(diag) + _("Filesystem cipher: \"%s\", version %i:%i:%i"), + config.cipher().name().c_str(), config.cipher().major(), + config.cipher().minor(), config.cipher().age()); // check if we support this interface.. - if(!cipher) + if (!cipher) cout << _(" (NOT supported)\n"); - else - { + else { // if we're using a newer interface, show the version number - if( config.cipher() != cipher->interface() ) - { + if (config.cipher() != cipher->interface()) { Interface iface = cipher->interface(); // xgroup(diag) - cout << autosprintf(_(" (using %i:%i:%i)\n"), - iface.major(), iface.minor(), iface.age()); + cout << autosprintf(_(" (using %i:%i:%i)\n"), iface.major(), + iface.minor(), iface.age()); } else cout << "\n"; } @@ -1197,28 +1062,23 @@ void showFSInfo( const EncfsConfig &config ) // xgroup(diag) cout << autosprintf(_("Filename encoding: \"%s\", version %i:%i:%i"), - config.naming().name().c_str(), config.naming().major(), - config.naming().minor(), config.naming().age()); - - if (!cipher) - { - cout << "\n"; - } else - { + config.naming().name().c_str(), config.naming().major(), + config.naming().minor(), config.naming().age()); + + if (!cipher) { + cout << "\n"; + } else { // check if we support the filename encoding interface.. - shared_ptr nameCoder = NameIO::New( config.naming(), cipher ); - if(!nameCoder) - { + shared_ptr nameCoder = NameIO::New(config.naming(), cipher); + if (!nameCoder) { // xgroup(diag) cout << _(" (NOT supported)\n"); - } else - { + } else { // if we're using a newer interface, show the version number - if( config.naming() != nameCoder->interface() ) - { + if (config.naming() != nameCoder->interface()) { Interface iface = nameCoder->interface(); - cout << autosprintf(_(" (using %i:%i:%i)\n"), - iface.major(), iface.minor(), iface.age()); + cout << autosprintf(_(" (using %i:%i:%i)\n"), iface.major(), + iface.minor(), iface.age()); } else cout << "\n"; } @@ -1227,125 +1087,108 @@ void showFSInfo( const EncfsConfig &config ) { cout << autosprintf(_("Key Size: %i bits"), 8 * key.size()); cipher = getCipher(config); - if(!cipher) - { + if (!cipher) { // xgroup(diag) cout << _(" (NOT supported)\n"); } else cout << "\n"; } - if(key.kdf_iterations() > 0 && key.salt().size() > 0) - { - cout << autosprintf(_("Using PBKDF2, with %i iterations"), - key.kdf_iterations()) << "\n"; - cout << autosprintf(_("Salt Size: %i bits"), - 8*(int)key.salt().size()) << "\n"; + if (key.kdf_iterations() > 0 && key.salt().size() > 0) { + cout << autosprintf(_("Using PBKDF2, with %i iterations"), + key.kdf_iterations()) << "\n"; + cout << autosprintf(_("Salt Size: %i bits"), 8 * (int)key.salt().size()) + << "\n"; } - if(config.block_mac_bytes() || config.block_mac_rand_bytes()) - { - if(config.revision() < V5Latest) - { + if (config.block_mac_bytes() || config.block_mac_rand_bytes()) { + if (config.revision() < V5Latest) { cout << autosprintf( - // xgroup(diag) - _("Block Size: %i bytes + %i byte MAC header"), - config.block_size(), - config.block_mac_bytes() + config.block_mac_rand_bytes()) << endl; - } else - { + // xgroup(diag) + _("Block Size: %i bytes + %i byte MAC header"), + config.block_size(), + config.block_mac_bytes() + config.block_mac_rand_bytes()) + << endl; + } else { // new version stores the header as part of that block size.. cout << autosprintf( - // xgroup(diag) - _("Block Size: %i bytes, including %i byte MAC header"), - config.block_size(), - config.block_mac_bytes() + config.block_mac_rand_bytes()) << endl; + // xgroup(diag) + _("Block Size: %i bytes, including %i byte MAC header"), + config.block_size(), + config.block_mac_bytes() + config.block_mac_rand_bytes()) + << endl; } - } else - { + } else { // xgroup(diag) cout << autosprintf(_("Block Size: %i bytes"), config.block_size()); cout << "\n"; } - if(config.unique_iv()) - { + if (config.unique_iv()) { // xgroup(diag) cout << _("Each file contains 8 byte header with unique IV data.\n"); } - if(config.chained_iv()) - { + if (config.chained_iv()) { // xgroup(diag) cout << _("Filenames encoded using IV chaining mode.\n"); } - if(config.external_iv()) - { + if (config.external_iv()) { // xgroup(diag) cout << _("File data IV is chained to filename IV.\n"); } - if(config.allow_holes()) - { + if (config.allow_holes()) { // xgroup(diag) cout << _("File holes passed through to ciphertext.\n"); } cout << "\n"; } -shared_ptr getCipher(const EncfsConfig &config) -{ +shared_ptr getCipher(const EncfsConfig &config) { return getCipher(config.cipher(), 8 * config.key().size()); } -shared_ptr getCipher(const Interface &iface, int keySize) -{ - return CipherV1::New( iface, keySize ); +shared_ptr getCipher(const Interface &iface, int keySize) { + return CipherV1::New(iface, keySize); } -CipherKey makeNewKey(EncfsConfig &config, const char *password, int passwdLen) -{ +CipherKey makeNewKey(EncfsConfig &config, const char *password, int passwdLen) { CipherKey userKey; shared_ptr cipher = getCipher(config); EncryptedKey *key = config.mutable_key(); unsigned char salt[20]; - if(!cipher->pseudoRandomize( salt, sizeof(salt))) - { + if (!cipher->pseudoRandomize(salt, sizeof(salt))) { cout << _("Error creating salt\n"); return userKey; } key->set_salt(salt, sizeof(salt)); int iterations = key->kdf_iterations(); - userKey = cipher->newKey(password, passwdLen, - &iterations, key->kdf_duration(), - salt, sizeof(salt)); + userKey = cipher->newKey(password, passwdLen, &iterations, + key->kdf_duration(), salt, sizeof(salt)); key->set_kdf_iterations(iterations); return userKey; } -CipherKey decryptKey(const EncfsConfig &config, const char *password, int passwdLen) -{ +CipherKey decryptKey(const EncfsConfig &config, const char *password, + int passwdLen) { const EncryptedKey &key = config.key(); CipherKey userKey; shared_ptr cipher = getCipher(config.cipher(), 8 * key.size()); - if(!key.salt().empty()) - { + if (!key.salt().empty()) { int iterations = key.kdf_iterations(); - userKey = cipher->newKey(password, passwdLen, - &iterations, key.kdf_duration(), - (const byte *)key.salt().data(), - key.salt().size()); + userKey = + cipher->newKey(password, passwdLen, &iterations, key.kdf_duration(), + (const byte *)key.salt().data(), key.salt().size()); - if (iterations != key.kdf_iterations()) - { + if (iterations != key.kdf_iterations()) { LOG(ERROR) << "Error in KDF, iteration mismatch"; return userKey; } - } else - { + } else { // old KDF, no salt.. - userKey = cipher->newKey( password, passwdLen ); + userKey = cipher->newKey(password, passwdLen); } return userKey; @@ -1353,18 +1196,15 @@ CipherKey decryptKey(const EncfsConfig &config, const char *password, int passwd // Doesn't use SecureMem, since we don't know how much will be read. // Besides, password is being produced by another program. -std::string readPassword( int FD ) -{ +std::string readPassword(int FD) { SecureMem *buf = new SecureMem(1024); string result; - while(1) - { + while (1) { ssize_t rdSize = recv(FD, buf->data(), buf->size(), 0); - if(rdSize > 0) - { - result.append( (char*)buf->data(), rdSize ); + if (rdSize > 0) { + result.append((char *)buf->data(), rdSize); } else break; } @@ -1372,39 +1212,35 @@ std::string readPassword( int FD ) // chop off trailing "\n" if present.. // This is done so that we can use standard programs like ssh-askpass // without modification, as it returns trailing newline.. - if(!result.empty() && result[ result.length()-1 ] == '\n' ) - result.resize( result.length() -1 ); + if (!result.empty() && result[result.length() - 1] == '\n') + result.resize(result.length() - 1); delete buf; return result; } SecureMem *passwordFromProgram(const std::string &passProg, - const std::string &rootDir) -{ + const std::string &rootDir) { // have a child process run the command and get the result back to us. int fds[2], pid; int res; res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds); - if(res == -1) - { + if (res == -1) { perror(_("Internal error: socketpair() failed")); return NULL; } VLOG(1) << "getUserKey: fds = " << fds[0] << ", " << fds[1]; pid = fork(); - if(pid == -1) - { + if (pid == -1) { perror(_("Internal error: fork() failed")); close(fds[0]); close(fds[1]); return NULL; } - if(pid == 0) - { + if (pid == 0) { const char *argv[4]; argv[0] = "/bin/sh"; argv[1] = "-c"; @@ -1412,18 +1248,18 @@ SecureMem *passwordFromProgram(const std::string &passProg, argv[3] = 0; // child process.. run the command and send output to fds[0] - close(fds[1]); // we don't use the other half.. + close(fds[1]); // we don't use the other half.. // make a copy of stdout and stderr descriptors, and set an environment // variable telling where to find them, in case a child wants it.. - int stdOutCopy = dup( STDOUT_FILENO ); - int stdErrCopy = dup( STDERR_FILENO ); + int stdOutCopy = dup(STDOUT_FILENO); + int stdErrCopy = dup(STDERR_FILENO); // replace STDOUT with our socket, which we'll used to receive the // password.. - dup2( fds[0], STDOUT_FILENO ); + dup2(fds[0], STDOUT_FILENO); // ensure that STDOUT_FILENO and stdout/stderr are not closed on exec.. - fcntl(STDOUT_FILENO, F_SETFD, 0); // don't close on exec.. + fcntl(STDOUT_FILENO, F_SETFD, 0); // don't close on exec.. fcntl(stdOutCopy, F_SETFD, 0); fcntl(stdErrCopy, F_SETFD, 0); @@ -1431,13 +1267,13 @@ SecureMem *passwordFromProgram(const std::string &passProg, setenv(ENCFS_ENV_ROOTDIR, rootDir.c_str(), 1); - snprintf(tmpBuf, sizeof(tmpBuf)-1, "%i", stdOutCopy); + snprintf(tmpBuf, sizeof(tmpBuf) - 1, "%i", stdOutCopy); setenv(ENCFS_ENV_STDOUT, tmpBuf, 1); - snprintf(tmpBuf, sizeof(tmpBuf)-1, "%i", stdErrCopy); + snprintf(tmpBuf, sizeof(tmpBuf) - 1, "%i", stdErrCopy); setenv(ENCFS_ENV_STDERR, tmpBuf, 1); - execvp( argv[0], (char * const *)argv ); // returns only on error.. + execvp(argv[0], (char * const *)argv); // returns only on error.. perror(_("Internal error: failed to exec program")); exit(1); @@ -1449,77 +1285,67 @@ SecureMem *passwordFromProgram(const std::string &passProg, waitpid(pid, NULL, 0); - SecureMem *result = new SecureMem(password.length()+1); - if (result) - strncpy((char *)result->data(), password.c_str(), result->size()); + SecureMem *result = new SecureMem(password.length() + 1); + if (result) strncpy((char *)result->data(), password.c_str(), result->size()); password.assign(password.length(), '\0'); return result; } -SecureMem *passwordFromStdin() -{ +SecureMem *passwordFromStdin() { SecureMem *buf = new SecureMem(MaxPassBuf); - char *res = fgets( (char *)buf->data(), buf->size(), stdin ); - if (res) - { + char *res = fgets((char *)buf->data(), buf->size(), stdin); + if (res) { // Kill the trailing newline. int last = strnlen((char *)buf->data(), buf->size()); - if (last > 0 && buf->data()[last-1] == '\n') - buf->data()[ last-1 ] = '\0'; + if (last > 0 && buf->data()[last - 1] == '\n') buf->data()[last - 1] = '\0'; } - + return buf; } -SecureMem *passwordFromPrompt() -{ +SecureMem *passwordFromPrompt() { SecureMem *buf = new SecureMem(MaxPassBuf); // xgroup(common) - char *res = readpassphrase( _("EncFS Password: "), - (char *)buf->data(), buf->size()-1, RPP_ECHO_OFF ); - if (!res) - { + char *res = readpassphrase(_("EncFS Password: "), (char *)buf->data(), + buf->size() - 1, RPP_ECHO_OFF); + if (!res) { delete buf; buf = NULL; } - + return buf; } -SecureMem *passwordFromPrompts() -{ +SecureMem *passwordFromPrompts() { SecureMem *buf = new SecureMem(MaxPassBuf); SecureMem *buf2 = new SecureMem(MaxPassBuf); - do - { + do { // xgroup(common) - char *res1 = readpassphrase(_("New Encfs Password: "), - (char *)buf->data(), buf->size()-1, RPP_ECHO_OFF); + char *res1 = readpassphrase(_("New Encfs Password: "), (char *)buf->data(), + buf->size() - 1, RPP_ECHO_OFF); // xgroup(common) - char *res2 = readpassphrase(_("Verify Encfs Password: "), - (char *)buf2->data(), buf2->size()-1, RPP_ECHO_OFF); + char *res2 = + readpassphrase(_("Verify Encfs Password: "), (char *)buf2->data(), + buf2->size() - 1, RPP_ECHO_OFF); - if(res1 && res2 - && !strncmp((char*)buf->data(), (char*)buf2->data(), MaxPassBuf)) - { - break; - } else - { + if (res1 && res2 && + !strncmp((char *)buf->data(), (char *)buf2->data(), MaxPassBuf)) { + break; + } else { // xgroup(common) -- probably not common, but group with the others cerr << _("Passwords did not match, please try again\n"); } - } while(1); + } while (1); delete buf2; return buf; } -CipherKey getUserKey(const EncfsConfig &config, bool useStdin) -{ +CipherKey getUserKey(const EncfsConfig &config, bool useStdin) { CipherKey userKey; SecureMem *password; @@ -1528,36 +1354,32 @@ CipherKey getUserKey(const EncfsConfig &config, bool useStdin) else password = passwordFromPrompt(); - if (password) - { - userKey = decryptKey(config, (char*)password->data(), - strlen((char*)password->data())); + if (password) { + userKey = decryptKey(config, (char *)password->data(), + strlen((char *)password->data())); delete password; } return userKey; } -CipherKey getUserKey( const EncfsConfig &config, const std::string &passProg, - const std::string &rootDir ) -{ +CipherKey getUserKey(const EncfsConfig &config, const std::string &passProg, + const std::string &rootDir) { CipherKey result; SecureMem *password = passwordFromProgram(passProg, rootDir); - if (password) - { - result = decryptKey(config, (char*)password->data(), - strlen((char*)password->data())); + if (password) { + result = decryptKey(config, (char *)password->data(), + strlen((char *)password->data())); delete password; } return result; } -CipherKey getNewUserKey(EncfsConfig &config, - bool useStdin, const std::string &passProg, - const std::string &rootDir) -{ +CipherKey getNewUserKey(EncfsConfig &config, bool useStdin, + const std::string &passProg, + const std::string &rootDir) { CipherKey result; SecureMem *password; @@ -1568,50 +1390,42 @@ CipherKey getNewUserKey(EncfsConfig &config, else password = passwordFromPrompts(); - if (password) - { - result = makeNewKey(config, (char*)password->data(), - strlen((char*)password->data())); + if (password) { + result = makeNewKey(config, (char *)password->data(), + strlen((char *)password->data())); delete password; } return result; } -RootPtr initFS( EncFS_Context *ctx, const shared_ptr &opts ) -{ +RootPtr initFS(EncFS_Context *ctx, const shared_ptr &opts) { RootPtr rootInfo; EncfsConfig config; - if(readConfig( opts->rootDir, config ) != Config_None) - { - if(opts->reverseEncryption) - { - if (config.block_mac_bytes() != 0 || config.block_mac_rand_bytes() != 0 - || config.unique_iv() || config.external_iv() - || config.chained_iv() ) - { - cout << _("The configuration loaded is not compatible with --reverse\n"); + if (readConfig(opts->rootDir, config) != Config_None) { + if (opts->reverseEncryption) { + if (config.block_mac_bytes() != 0 || config.block_mac_rand_bytes() != 0 || + config.unique_iv() || config.external_iv() || config.chained_iv()) { + cout + << _("The configuration loaded is not compatible with --reverse\n"); return rootInfo; } } // first, instanciate the cipher. shared_ptr cipher = getCipher(config); - if(!cipher) - { + if (!cipher) { Interface iface = config.cipher(); - LOG(ERROR) << "Unable to find cipher " << iface.name() - << ", version " << iface.major() - << ":" << iface.minor() << ":" << iface.age(); + LOG(ERROR) << "Unable to find cipher " << iface.name() << ", version " + << iface.major() << ":" << iface.minor() << ":" << iface.age(); // xgroup(diag) cout << _("The requested cipher interface is not available\n"); return rootInfo; } - if(opts->delayMount) - { - rootInfo = RootPtr( new EncFS_Root ); + if (opts->delayMount) { + rootInfo = RootPtr(new EncFS_Root); rootInfo->cipher = cipher; rootInfo->root = shared_ptr(); return rootInfo; @@ -1620,27 +1434,24 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr &opts ) // get user key CipherKey userKey; - if(opts->passwordProgram.empty()) - { - if (opts->annotate) - cerr << "$PROMPT$ passwd" << endl; - userKey = getUserKey( config, opts->useStdin ); + if (opts->passwordProgram.empty()) { + if (opts->annotate) cerr << "$PROMPT$ passwd" << endl; + userKey = getUserKey(config, opts->useStdin); } else - userKey = getUserKey( config, opts->passwordProgram, opts->rootDir ); + userKey = getUserKey(config, opts->passwordProgram, opts->rootDir); - if(!userKey.valid()) - return rootInfo; + if (!userKey.valid()) return rootInfo; - cipher->setKey(userKey); + cipher->setKey(userKey); VLOG(1) << "cipher encoded key size = " << cipher->encodedKeySize(); // decode volume key.. - CipherKey volumeKey = cipher->readKey( - (const unsigned char *)config.key().ciphertext().data(), opts->checkKey); + CipherKey volumeKey = + cipher->readKey((const unsigned char *)config.key().ciphertext().data(), + opts->checkKey); userKey.reset(); - if(!volumeKey.valid()) - { + if (!volumeKey.valid()) { // xgroup(diag) cout << _("Error decoding volume key, password incorrect\n"); return rootInfo; @@ -1648,23 +1459,22 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr &opts ) cipher->setKey(volumeKey); - shared_ptr nameCoder = NameIO::New( config.naming(), cipher ); - if(!nameCoder) - { + shared_ptr nameCoder = NameIO::New(config.naming(), cipher); + if (!nameCoder) { Interface iface = config.naming(); LOG(ERROR) << "Unable to find nameio interface " << iface.name() - << ", version " << iface.major() - << ":" << iface.minor() << ":" << iface.age(); + << ", version " << iface.major() << ":" << iface.minor() << ":" + << iface.age(); // xgroup(diag) cout << _("The requested filename coding interface is " - "not available\n"); + "not available\n"); return rootInfo; } - nameCoder->setChainedNameIV( config.chained_iv() ); - nameCoder->setReverseEncryption( opts->reverseEncryption ); + nameCoder->setChainedNameIV(config.chained_iv()); + nameCoder->setReverseEncryption(opts->reverseEncryption); - FSConfigPtr fsConfig( new FSConfig ); + FSConfigPtr fsConfig(new FSConfig); fsConfig->cipher = cipher; fsConfig->key = volumeKey; fsConfig->nameCoding = nameCoder; @@ -1673,34 +1483,29 @@ RootPtr initFS( EncFS_Context *ctx, const shared_ptr &opts ) fsConfig->reverseEncryption = opts->reverseEncryption; fsConfig->opts = opts; - rootInfo = RootPtr( new EncFS_Root ); + rootInfo = RootPtr(new EncFS_Root); rootInfo->cipher = cipher; rootInfo->volumeKey = volumeKey; - rootInfo->root = shared_ptr( - new DirNode( ctx, opts->rootDir, fsConfig )); - } else - { - if(opts->createIfNotFound) - { + rootInfo->root = + shared_ptr(new DirNode(ctx, opts->rootDir, fsConfig)); + } else { + if (opts->createIfNotFound) { // creating a new encrypted filesystem - rootInfo = createConfig( ctx, opts ); + rootInfo = createConfig(ctx, opts); } } return rootInfo; } -int remountFS(EncFS_Context *ctx) -{ +int remountFS(EncFS_Context *ctx) { VLOG(1) << "Attempting to reinitialize filesystem"; - RootPtr rootInfo = initFS( ctx, ctx->opts ); - if(rootInfo) - { + RootPtr rootInfo = initFS(ctx, ctx->opts); + if (rootInfo) { ctx->setRoot(rootInfo->root); return 0; - } else - { + } else { LOG(WARNING) << "Remount failed"; return -EACCES; } diff --git a/fs/FileUtils.h b/fs/FileUtils.h index a821838..a8df155 100644 --- a/fs/FileUtils.h +++ b/fs/FileUtils.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + #ifndef _FileUtils_incl_ #define _FileUtils_incl_ @@ -29,26 +29,25 @@ namespace encfs { // true if the path points to an existing node (of any type) -bool fileExists( const char *fileName ); +bool fileExists(const char *fileName); // true if path is a directory -bool isDirectory( const char *fileName ); +bool isDirectory(const char *fileName); // true if starts with '/' -bool isAbsolutePath( const char *fileName ); +bool isAbsolutePath(const char *fileName); // pointer to just after the last '/' -const char *lastPathElement( const char *name ); +const char *lastPathElement(const char *name); -std::string parentDirectory( const std::string &path ); +std::string parentDirectory(const std::string &path); // ask the user for permission to create the directory. If they say ok, then // do it and return true. -bool userAllowMkdir(const char *dirPath, mode_t mode ); -bool userAllowMkdir(int promptno, const char *dirPath, mode_t mode ); +bool userAllowMkdir(const char *dirPath, mode_t mode); +bool userAllowMkdir(int promptno, const char *dirPath, mode_t mode); class CipherV1; class DirNode; -struct EncFS_Root -{ +struct EncFS_Root { shared_ptr cipher; CipherKey volumeKey; shared_ptr root; @@ -59,36 +58,33 @@ struct EncFS_Root typedef shared_ptr RootPtr; -enum ConfigMode -{ +enum ConfigMode { Config_Prompt, Config_Standard, Config_Paranoia }; -struct EncFS_Opts -{ +struct EncFS_Opts { std::string rootDir; bool createIfNotFound; // create filesystem if not found - bool idleTracking; // turn on idle monitoring of filesystem - bool mountOnDemand; // mounting on-demand - bool delayMount; // delay initial mount + bool idleTracking; // turn on idle monitoring of filesystem + bool mountOnDemand; // mounting on-demand + bool delayMount; // delay initial mount - bool checkKey; // check crypto key decoding - bool forceDecode; // force decode on MAC block failures + bool checkKey; // check crypto key decoding + bool forceDecode; // force decode on MAC block failures - std::string passwordProgram; // path to password program (or empty) - bool useStdin; // read password from stdin rather then prompting - bool annotate; // print annotation line prompt to stderr. + std::string passwordProgram; // path to password program (or empty) + bool useStdin; // read password from stdin rather then prompting + bool annotate; // print annotation line prompt to stderr. - bool ownerCreate; // set owner of new files to caller + bool ownerCreate; // set owner of new files to caller - bool reverseEncryption; // Reverse encryption + bool reverseEncryption; // Reverse encryption ConfigMode configMode; - EncFS_Opts() - { + EncFS_Opts() { createIfNotFound = true; idleTracking = false; mountOnDemand = false; @@ -106,35 +102,33 @@ struct EncFS_Opts /* Read existing config file. Looks for any supported configuration version. */ -ConfigType readConfig( const std::string &rootDir, EncfsConfig &config ); +ConfigType readConfig(const std::string &rootDir, EncfsConfig &config); /* Save the configuration. Saves back as the same configuration type as was read from. */ -bool saveConfig( const std::string &rootdir, const EncfsConfig &config ); +bool saveConfig(const std::string &rootdir, const EncfsConfig &config); class EncFS_Context; -RootPtr initFS( EncFS_Context *ctx, const shared_ptr &opts ); +RootPtr initFS(EncFS_Context *ctx, const shared_ptr &opts); -RootPtr createConfig( EncFS_Context *ctx, - const shared_ptr &opts ); +RootPtr createConfig(EncFS_Context *ctx, const shared_ptr &opts); -void showFSInfo( const EncfsConfig &config ); +void showFSInfo(const EncfsConfig &config); -bool readV4Config( const char *configFile, EncfsConfig &config, - struct ConfigInfo *); +bool readV4Config(const char *configFile, EncfsConfig &config, + struct ConfigInfo *); -bool readV5Config( const char *configFile, EncfsConfig &config, - struct ConfigInfo *); +bool readV5Config(const char *configFile, EncfsConfig &config, + struct ConfigInfo *); -bool readV6Config( const char *configFile, EncfsConfig &config, - struct ConfigInfo *); - -bool readProtoConfig( const char *configFile, EncfsConfig &config, - struct ConfigInfo *); +bool readV6Config(const char *configFile, EncfsConfig &config, + struct ConfigInfo *); +bool readProtoConfig(const char *configFile, EncfsConfig &config, + struct ConfigInfo *); } // namespace encfs #endif diff --git a/fs/MACFileIO.cpp b/fs/MACFileIO.cpp index db48c81..64ef3f6 100644 --- a/fs/MACFileIO.cpp +++ b/fs/MACFileIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -47,64 +47,44 @@ namespace encfs { // static Interface MACFileIO_iface = makeInterface("FileIO/MAC", 2, 1, 0); -int dataBlockSize(const FSConfigPtr &cfg) -{ - return cfg->config->block_size() - - cfg->config->block_mac_bytes() - - cfg->config->block_mac_rand_bytes(); +int dataBlockSize(const FSConfigPtr &cfg) { + return cfg->config->block_size() - cfg->config->block_mac_bytes() - + cfg->config->block_mac_rand_bytes(); } -MACFileIO::MACFileIO( const shared_ptr &_base, - const FSConfigPtr &cfg ) - : BlockFileIO( dataBlockSize( cfg ), cfg ) - , base( _base ) - , cipher( cfg->cipher ) - , macBytes( cfg->config->block_mac_bytes() ) - , randBytes( cfg->config->block_mac_rand_bytes() ) - , warnOnly( cfg->opts->forceDecode ) -{ - rAssert( macBytes >= 0 && macBytes <= 8 ); - rAssert( randBytes >= 0 ); +MACFileIO::MACFileIO(const shared_ptr &_base, const FSConfigPtr &cfg) + : BlockFileIO(dataBlockSize(cfg), cfg), + base(_base), + cipher(cfg->cipher), + macBytes(cfg->config->block_mac_bytes()), + randBytes(cfg->config->block_mac_rand_bytes()), + warnOnly(cfg->opts->forceDecode) { + rAssert(macBytes >= 0 && macBytes <= 8); + rAssert(randBytes >= 0); VLOG(1) << "fs block size = " << cfg->config->block_size() - << ", macBytes = " << cfg->config->block_mac_bytes() - << ", randBytes = " << cfg->config->block_mac_rand_bytes(); + << ", macBytes = " << cfg->config->block_mac_bytes() + << ", randBytes = " << cfg->config->block_mac_rand_bytes(); } -MACFileIO::~MACFileIO() -{ +MACFileIO::~MACFileIO() {} + +Interface MACFileIO::interface() const { return MACFileIO_iface; } + +int MACFileIO::open(int flags) { return base->open(flags); } + +void MACFileIO::setFileName(const char *fileName) { + base->setFileName(fileName); } -Interface MACFileIO::interface() const -{ - return MACFileIO_iface; -} +const char *MACFileIO::getFileName() const { return base->getFileName(); } -int MACFileIO::open( int flags ) -{ - return base->open( flags ); -} +bool MACFileIO::setIV(uint64_t iv) { return base->setIV(iv); } -void MACFileIO::setFileName( const char *fileName ) -{ - base->setFileName( fileName ); -} - -const char *MACFileIO::getFileName() const -{ - return base->getFileName(); -} - -bool MACFileIO::setIV( uint64_t iv ) -{ - return base->setIV( iv ); -} - -inline static off_t roundUpDivide( off_t numerator, int denominator ) -{ +inline static off_t roundUpDivide(off_t numerator, int denominator) { // integer arithmetic always rounds down, so we can round up by adding // enough so that any value other then a multiple of denominator gets // rouned to the next highest value. - return ( numerator + denominator - 1 ) / denominator; + return (numerator + denominator - 1) / denominator; } // Convert from a location in the raw file to a location when MAC headers are @@ -117,9 +97,8 @@ inline static off_t roundUpDivide( off_t numerator, int denominator ) // ... blockNum = 1 // ... partialBlock = 0 // ... adjLoc = 1 * blockSize -static off_t locWithHeader( off_t offset, int blockSize, int headerSize ) -{ - off_t blockNum = roundUpDivide( offset , blockSize - headerSize ); +static off_t locWithHeader(off_t offset, int blockSize, int headerSize) { + off_t blockNum = roundUpDivide(offset, blockSize - headerSize); return offset + blockNum * headerSize; } @@ -128,92 +107,77 @@ static off_t locWithHeader( off_t offset, int blockSize, int headerSize ) // The output value will always be less then the input value, because the // headers are stored at the beginning of the block, so even the first data is // offset by the size of the header. -static off_t locWithoutHeader( off_t offset, int blockSize, int headerSize ) -{ - off_t blockNum = roundUpDivide( offset , blockSize ); +static off_t locWithoutHeader(off_t offset, int blockSize, int headerSize) { + off_t blockNum = roundUpDivide(offset, blockSize); return offset - blockNum * headerSize; } -int MACFileIO::getAttr( struct stat *stbuf ) const -{ - int res = base->getAttr( stbuf ); +int MACFileIO::getAttr(struct stat *stbuf) const { + int res = base->getAttr(stbuf); - if(res == 0 && S_ISREG(stbuf->st_mode)) - { + if (res == 0 && S_ISREG(stbuf->st_mode)) { // have to adjust size field.. int headerSize = macBytes + randBytes; int bs = blockSize() + headerSize; - stbuf->st_size = locWithoutHeader( stbuf->st_size, bs, headerSize ); + stbuf->st_size = locWithoutHeader(stbuf->st_size, bs, headerSize); } return res; } -off_t MACFileIO::getSize() const -{ +off_t MACFileIO::getSize() const { // adjust the size to hide the header overhead we tack on.. int headerSize = macBytes + randBytes; int bs = blockSize() + headerSize; off_t size = base->getSize(); - if(size > 0) - size = locWithoutHeader( size, bs, headerSize ); + if (size > 0) size = locWithoutHeader(size, bs, headerSize); return size; } -ssize_t MACFileIO::readOneBlock( const IORequest &req ) const -{ +ssize_t MACFileIO::readOneBlock(const IORequest &req) const { int headerSize = macBytes + randBytes; int bs = blockSize() + headerSize; MemBlock mb; - mb.allocate( bs ); + mb.allocate(bs); IORequest tmp; - tmp.offset = locWithHeader( req.offset, bs, headerSize ); + tmp.offset = locWithHeader(req.offset, bs, headerSize); tmp.data = mb.data; tmp.dataLen = headerSize + req.dataLen; // get the data from the base FileIO layer - ssize_t readSize = base->read( tmp ); + ssize_t readSize = base->read(tmp); // don't store zeros if configured for zero-block pass-through bool skipBlock = true; - if( _allowHoles ) - { - for(int i=0; i 0) - skipBlock = false; + } else if (macBytes > 0) + skipBlock = false; - if(readSize > headerSize) - { - if(!skipBlock) - { + if (readSize > headerSize) { + if (!skipBlock) { // At this point the data has been decoded. So, compute the MAC of // the block and check against the checksum stored in the header.. - uint64_t mac = cipher->MAC_64( tmp.data + macBytes, - readSize - macBytes ); + uint64_t mac = cipher->MAC_64(tmp.data + macBytes, readSize - macBytes); - for(int i=0; i>= 8) - { + for (int i = 0; i < macBytes; ++i, mac >>= 8) { int test = mac & 0xff; int stored = tmp.data[i]; - if(test != stored) - { - // uh oh.. + if (test != stored) { + // uh oh.. long blockNum = req.offset / bs; LOG(WARNING) << "MAC comparison failure in block " << blockNum; - if( !warnOnly ) - { - throw Error( - _("MAC comparison failure, refusing to read")); + if (!warnOnly) { + throw Error(_("MAC comparison failure, refusing to read")); } break; } @@ -222,75 +186,64 @@ ssize_t MACFileIO::readOneBlock( const IORequest &req ) const // now copy the data to the output buffer readSize -= headerSize; - memcpy( req.data, tmp.data + headerSize, readSize ); - } else - { + memcpy(req.data, tmp.data + headerSize, readSize); + } else { VLOG(1) << "readSize " << readSize << " at offset " << req.offset; - if(readSize > 0) - readSize = 0; + if (readSize > 0) readSize = 0; } return readSize; } -bool MACFileIO::writeOneBlock( const IORequest &req ) -{ +bool MACFileIO::writeOneBlock(const IORequest &req) { int headerSize = macBytes + randBytes; int bs = blockSize() + headerSize; // we have the unencrypted data, so we need to attach a header to it. MemBlock mb; - mb.allocate( bs ); + mb.allocate(bs); IORequest newReq; - newReq.offset = locWithHeader( req.offset, bs, headerSize ); + newReq.offset = locWithHeader(req.offset, bs, headerSize); newReq.data = mb.data; newReq.dataLen = headerSize + req.dataLen; - memset( newReq.data, 0, headerSize ); - memcpy( newReq.data + headerSize, req.data, req.dataLen ); - if(randBytes > 0) - { - if(!cipher->pseudoRandomize( newReq.data+macBytes, randBytes)) + memset(newReq.data, 0, headerSize); + memcpy(newReq.data + headerSize, req.data, req.dataLen); + if (randBytes > 0) { + if (!cipher->pseudoRandomize(newReq.data + macBytes, randBytes)) return false; } - if(macBytes > 0) - { + if (macBytes > 0) { // compute the mac (which includes the random data) and fill it in - uint64_t mac = cipher->MAC_64( newReq.data+macBytes, - req.dataLen + randBytes ); + uint64_t mac = + cipher->MAC_64(newReq.data + macBytes, req.dataLen + randBytes); - for(int i=0; i>= 8; } } // now, we can let the next level have it.. - bool ok = base->write( newReq ); + bool ok = base->write(newReq); return ok; } -int MACFileIO::truncate( off_t size ) -{ +int MACFileIO::truncate(off_t size) { int headerSize = macBytes + randBytes; int bs = blockSize() + headerSize; - int res = blockTruncate( size, 0 ); + int res = blockTruncate(size, 0); - if(res == 0) - base->truncate( locWithHeader( size, bs, headerSize ) ); + if (res == 0) base->truncate(locWithHeader(size, bs, headerSize)); return res; } -bool MACFileIO::isWritable() const -{ - return base->isWritable(); -} +bool MACFileIO::isWritable() const { return base->isWritable(); } } // namespace encfs diff --git a/fs/MACFileIO.h b/fs/MACFileIO.h index 07974d5..d3d676c 100644 --- a/fs/MACFileIO.h +++ b/fs/MACFileIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -26,45 +26,42 @@ namespace encfs { -class MACFileIO : public BlockFileIO -{ -public: - /* - If warnOnlyMode is enabled, then a MAC comparison failure will only - result in a warning message from encfs -- the garbled data will still - be made available.. - */ - MACFileIO( const shared_ptr &base, - const FSConfigPtr &cfg ); - MACFileIO(); - virtual ~MACFileIO(); +class MACFileIO : public BlockFileIO { + public: + /* + If warnOnlyMode is enabled, then a MAC comparison failure will only + result in a warning message from encfs -- the garbled data will still + be made available.. + */ + MACFileIO(const shared_ptr &base, const FSConfigPtr &cfg); + MACFileIO(); + virtual ~MACFileIO(); - virtual Interface interface() const; + virtual Interface interface() const; - virtual void setFileName( const char *fileName ); - virtual const char *getFileName() const; - virtual bool setIV( uint64_t iv ); + virtual void setFileName(const char *fileName); + virtual const char *getFileName() const; + virtual bool setIV(uint64_t iv); - virtual int open( int flags ); - virtual int getAttr( struct stat *stbuf ) const; - virtual off_t getSize() const; + virtual int open(int flags); + virtual int getAttr(struct stat *stbuf) const; + virtual off_t getSize() const; - virtual int truncate( off_t size ); + virtual int truncate(off_t size); - virtual bool isWritable() const; + virtual bool isWritable() const; -private: - virtual ssize_t readOneBlock( const IORequest &req ) const; - virtual bool writeOneBlock( const IORequest &req ); + private: + virtual ssize_t readOneBlock(const IORequest &req) const; + virtual bool writeOneBlock(const IORequest &req); - shared_ptr base; - shared_ptr cipher; - int macBytes; - int randBytes; - bool warnOnly; + shared_ptr base; + shared_ptr cipher; + int macBytes; + int randBytes; + bool warnOnly; }; } // namespace encfs #endif - diff --git a/fs/MemBlockFileIO.cpp b/fs/MemBlockFileIO.cpp index dd85989..92eef12 100644 --- a/fs/MemBlockFileIO.cpp +++ b/fs/MemBlockFileIO.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -26,39 +26,29 @@ namespace encfs { -static Interface MemBlockFileIO_iface = makeInterface("FileIO/MemBlock", - 1, 0, 0); +static Interface MemBlockFileIO_iface = + makeInterface("FileIO/MemBlock", 1, 0, 0); -MemBlockFileIO::MemBlockFileIO(int blockSize, const FSConfigPtr &cfg) - : BlockFileIO(blockSize, cfg), impl(new MemFileIO(0)) { -} +MemBlockFileIO::MemBlockFileIO(int blockSize, const FSConfigPtr& cfg) + : BlockFileIO(blockSize, cfg), impl(new MemFileIO(0)) {} -MemBlockFileIO::~MemBlockFileIO() { -} +MemBlockFileIO::~MemBlockFileIO() {} -Interface MemBlockFileIO::interface() const { - return MemBlockFileIO_iface; -} +Interface MemBlockFileIO::interface() const { return MemBlockFileIO_iface; } -void MemBlockFileIO::setFileName(const char *name) { +void MemBlockFileIO::setFileName(const char* name) { return impl->setFileName(name); } -const char *MemBlockFileIO::getFileName() const { - return impl->getFileName(); -} +const char* MemBlockFileIO::getFileName() const { return impl->getFileName(); } -int MemBlockFileIO::open(int flags) { - return impl->open(flags); -} +int MemBlockFileIO::open(int flags) { return impl->open(flags); } int MemBlockFileIO::getAttr(struct stat* stbuf) const { return impl->getAttr(stbuf); } -off_t MemBlockFileIO::getSize() const { - return impl->getSize(); -} +off_t MemBlockFileIO::getSize() const { return impl->getSize(); } ssize_t MemBlockFileIO::readOneBlock(const IORequest& req) const { return impl->read(req); @@ -68,12 +58,8 @@ bool MemBlockFileIO::writeOneBlock(const IORequest& req) { return impl->write(req); } -int MemBlockFileIO::truncate(off_t size) { - return impl->truncate(size); -} +int MemBlockFileIO::truncate(off_t size) { return impl->truncate(size); } -bool MemBlockFileIO::isWritable() const { - return impl->isWritable(); -} +bool MemBlockFileIO::isWritable() const { return impl->isWritable(); } } // namespace encfs diff --git a/fs/MemBlockFileIO.h b/fs/MemBlockFileIO.h index b1bf64e..8b13efa 100644 --- a/fs/MemBlockFileIO.h +++ b/fs/MemBlockFileIO.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -42,13 +42,14 @@ class MemBlockFileIO : public BlockFileIO { virtual const char *getFileName() const; virtual int open(int flags); - + virtual int getAttr(struct stat *stbuf) const; virtual off_t getSize() const; virtual bool isWritable() const; virtual int truncate(off_t size); + protected: virtual ssize_t readOneBlock(const IORequest &req) const; virtual bool writeOneBlock(const IORequest &req); @@ -60,4 +61,3 @@ class MemBlockFileIO : public BlockFileIO { } // namespace encfs #endif - diff --git a/fs/MemFileIO.cpp b/fs/MemFileIO.cpp index 0ca5a5b..6910db3 100644 --- a/fs/MemFileIO.cpp +++ b/fs/MemFileIO.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -34,25 +34,15 @@ MemFileIO* NewMemFileIO(const Interface& iface) { return new MemFileIO(0); } -MemFileIO::MemFileIO(int size) - : writable(false) { - buf.resize(size); -} +MemFileIO::MemFileIO(int size) : writable(false) { buf.resize(size); } -MemFileIO::~MemFileIO() { -} +MemFileIO::~MemFileIO() {} -Interface MemFileIO::interface() const { - return MemFileIO_iface; -} +Interface MemFileIO::interface() const { return MemFileIO_iface; } -void MemFileIO::setFileName(const char *name) { - this->name = name; -} +void MemFileIO::setFileName(const char* name) { this->name = name; } -const char *MemFileIO::getFileName() const { - return name.c_str(); -} +const char* MemFileIO::getFileName() const { return name.c_str(); } int MemFileIO::open(int flags) { bool requestWrite = ((flags & O_RDWR) || (flags & O_WRONLY)); @@ -67,9 +57,7 @@ int MemFileIO::getAttr(struct stat* stbuf) const { return 0; } -off_t MemFileIO::getSize() const { - return buf.size(); -} +off_t MemFileIO::getSize() const { return buf.size(); } ssize_t MemFileIO::read(const IORequest& req) const { rAssert(req.offset >= 0); @@ -102,8 +90,6 @@ int MemFileIO::truncate(off_t size) { return 0; } -bool MemFileIO::isWritable() const { - return writable; -} +bool MemFileIO::isWritable() const { return writable; } } // namespace encfs diff --git a/fs/MemFileIO.h b/fs/MemFileIO.h index 804a107..50f2afa 100644 --- a/fs/MemFileIO.h +++ b/fs/MemFileIO.h @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -40,12 +40,12 @@ class MemFileIO : public FileIO { virtual const char *getFileName() const; virtual int open(int flags); - + virtual int getAttr(struct stat *stbuf) const; virtual off_t getSize() const; - virtual ssize_t read(const IORequest& req) const; - virtual bool write(const IORequest& req); + virtual ssize_t read(const IORequest &req) const; + virtual bool write(const IORequest &req); virtual int truncate(off_t size); virtual bool isWritable() const; @@ -59,4 +59,3 @@ class MemFileIO : public FileIO { } // namespace encfs #endif - diff --git a/fs/NameIO.cpp b/fs/NameIO.cpp index b8c6740..4c2be73 100644 --- a/fs/NameIO.cpp +++ b/fs/NameIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -42,23 +42,18 @@ using std::string; namespace encfs { -#define REF_MODULE(TYPE) \ - do { \ - if(!TYPE::Enabled() ) \ - cerr << "referenceModule: should never happen\n"; \ - } while(0) +#define REF_MODULE(TYPE) \ + do { \ + if (!TYPE::Enabled()) cerr << "referenceModule: should never happen\n"; \ + } while (0) -static -void AddSymbolReferences() -{ +static void AddSymbolReferences() { REF_MODULE(BlockNameIO); REF_MODULE(StreamNameIO); REF_MODULE(NullNameIO); } - -struct NameIOAlg -{ +struct NameIOAlg { bool hidden; NameIO::Constructor constructor; string description; @@ -66,30 +61,25 @@ struct NameIOAlg bool needsStreamMode; }; -typedef multimap< string, NameIOAlg > NameIOMap_t; +typedef multimap NameIOMap_t; static NameIOMap_t *gNameIOMap = 0; - -list< NameIO::Algorithm > NameIO::GetAlgorithmList( bool includeHidden ) -{ +list NameIO::GetAlgorithmList(bool includeHidden) { AddSymbolReferences(); - list< Algorithm > result; - if(gNameIOMap) - { + list result; + if (gNameIOMap) { NameIOMap_t::const_iterator it; NameIOMap_t::const_iterator end = gNameIOMap->end(); - for(it = gNameIOMap->begin(); it != end; ++it) - { - if(includeHidden || !it->second.hidden) - { + for (it = gNameIOMap->begin(); it != end; ++it) { + if (includeHidden || !it->second.hidden) { Algorithm tmp; tmp.name = it->first; tmp.description = it->second.description; tmp.iface = it->second.iface; tmp.needsStreamMode = it->second.needsStreamMode; - result.push_back( tmp ); + result.push_back(tmp); } } } @@ -97,13 +87,10 @@ list< NameIO::Algorithm > NameIO::GetAlgorithmList( bool includeHidden ) return result; } -bool NameIO::Register( const char *name, const char *description, - const Interface &iface, Constructor constructor, - bool needsStreamMode, - bool hidden ) -{ - if( !gNameIOMap ) - gNameIOMap = new NameIOMap_t; +bool NameIO::Register(const char *name, const char *description, + const Interface &iface, Constructor constructor, + bool needsStreamMode, bool hidden) { + if (!gNameIOMap) gNameIOMap = new NameIOMap_t; NameIOAlg alg; alg.hidden = hidden; @@ -112,40 +99,33 @@ bool NameIO::Register( const char *name, const char *description, alg.iface = iface; alg.needsStreamMode = needsStreamMode; - gNameIOMap->insert( make_pair( string(name), alg )); + gNameIOMap->insert(make_pair(string(name), alg)); return true; } -shared_ptr NameIO::New(const string &name, - const shared_ptr &cipher) -{ +shared_ptr NameIO::New(const string &name, + const shared_ptr &cipher) { shared_ptr result; - if(gNameIOMap) - { - NameIOMap_t::const_iterator it = gNameIOMap->find( name ); - if(it != gNameIOMap->end()) - { + if (gNameIOMap) { + NameIOMap_t::const_iterator it = gNameIOMap->find(name); + if (it != gNameIOMap->end()) { Constructor fn = it->second.constructor; - result = (*fn)( it->second.iface, cipher ); + result = (*fn)(it->second.iface, cipher); } } return result; } -shared_ptr NameIO::New(const Interface &iface, - const shared_ptr &cipher) -{ +shared_ptr NameIO::New(const Interface &iface, + const shared_ptr &cipher) { shared_ptr result; - if(gNameIOMap) - { + if (gNameIOMap) { NameIOMap_t::const_iterator it; NameIOMap_t::const_iterator end = gNameIOMap->end(); - for(it = gNameIOMap->begin(); it != end; ++it) - { - if( implements(it->second.iface, iface )) - { + for (it = gNameIOMap->begin(); it != end; ++it) { + if (implements(it->second.iface, iface)) { Constructor fn = it->second.constructor; - result = (*fn)( iface, cipher ); + result = (*fn)(iface, cipher); break; } } @@ -153,195 +133,148 @@ shared_ptr NameIO::New(const Interface &iface, return result; } +NameIO::NameIO() : chainedNameIV(false), reverseEncryption(false) {} +NameIO::~NameIO() {} -NameIO::NameIO() - : chainedNameIV( false ), reverseEncryption( false ) -{ -} +void NameIO::setChainedNameIV(bool enable) { chainedNameIV = enable; } -NameIO::~NameIO() -{ -} +bool NameIO::getChainedNameIV() const { return chainedNameIV; } -void NameIO::setChainedNameIV( bool enable ) -{ - chainedNameIV = enable; -} +void NameIO::setReverseEncryption(bool enable) { reverseEncryption = enable; } -bool NameIO::getChainedNameIV() const -{ - return chainedNameIV; -} +bool NameIO::getReverseEncryption() const { return reverseEncryption; } -void NameIO::setReverseEncryption( bool enable ) -{ - reverseEncryption = enable; -} - -bool NameIO::getReverseEncryption() const -{ - return reverseEncryption; -} - - -std::string NameIO::recodePath( const char *path, - int (NameIO::*_length)(int) const, - int (NameIO::*_code)(const char*, int, uint64_t *, char*) const, - uint64_t *iv ) const -{ +std::string NameIO::recodePath(const char *path, + int (NameIO::*_length)(int) const, + int (NameIO::*_code)(const char *, int, + uint64_t *, char *) const, + uint64_t *iv) const { string output; - while( *path ) - { - if( *path == '/' ) - { - if( !output.empty() ) // don't start the string with '/' + while (*path) { + if (*path == '/') { + if (!output.empty()) // don't start the string with '/' output += '/'; ++path; - } else - { + } else { bool isDotFile = (*path == '.'); - const char *next = strchr( path, '/' ); - int len = next ? next - path : strlen( path ); + const char *next = strchr(path, '/'); + int len = next ? next - path : strlen(path); // at this point we know that len > 0 - if( isDotFile && (path[len-1] == '.') && (len <= 2) ) - { - output.append(len, '.'); // append [len] copies of '.' + if (isDotFile && (path[len - 1] == '.') && (len <= 2)) { + output.append(len, '.'); // append [len] copies of '.' path += len; continue; } // figure out buffer sizes - int approxLen = (this->*_length)( len ); - if(approxLen <= 0) - throw Error("Filename too small to decode"); + int approxLen = (this->*_length)(len); + if (approxLen <= 0) throw Error("Filename too small to decode"); - BUFFER_INIT( codeBuf, 32, (unsigned int)approxLen+1 ); + BUFFER_INIT(codeBuf, 32, (unsigned int)approxLen + 1); // code the name - int codedLen = (this->*_code)( path, len, iv, codeBuf ); - rAssert( codedLen <= approxLen ); - rAssert( codeBuf[codedLen] == '\0' ); + int codedLen = (this->*_code)(path, len, iv, codeBuf); + rAssert(codedLen <= approxLen); + rAssert(codeBuf[codedLen] == '\0'); path += len; // append result to string - output += (char*)codeBuf; + output += (char *)codeBuf; - BUFFER_RESET( codeBuf ); + BUFFER_RESET(codeBuf); } } return output; } -std::string NameIO::encodePath( const char *plaintextPath ) const -{ +std::string NameIO::encodePath(const char *plaintextPath) const { uint64_t iv = 0; - return encodePath( plaintextPath, &iv); + return encodePath(plaintextPath, &iv); } -std::string NameIO::decodePath( const char *cipherPath ) const -{ +std::string NameIO::decodePath(const char *cipherPath) const { uint64_t iv = 0; - return decodePath( cipherPath, &iv ); + return decodePath(cipherPath, &iv); } -std::string NameIO::_encodePath( const char *plaintextPath, uint64_t *iv ) const -{ - // if chaining is not enabled, then the iv pointer is not used.. - if(!chainedNameIV) - iv = 0; - return recodePath( plaintextPath, - &NameIO::maxEncodedNameLen, &NameIO::encodeName, iv); -} - -std::string NameIO::_decodePath( const char *cipherPath, uint64_t *iv ) const -{ +std::string NameIO::_encodePath(const char *plaintextPath, uint64_t *iv) const { // if chaining is not enabled, then the iv pointer is not used.. - if(!chainedNameIV) - iv = 0; - return recodePath( cipherPath, - &NameIO::maxDecodedNameLen, &NameIO::decodeName, iv); + if (!chainedNameIV) iv = 0; + return recodePath(plaintextPath, &NameIO::maxEncodedNameLen, + &NameIO::encodeName, iv); } -std::string NameIO::encodePath( const char *path, uint64_t *iv ) const -{ - return getReverseEncryption() ? - _decodePath( path, iv ) : - _encodePath( path, iv ); -} - -std::string NameIO::decodePath( const char *path, uint64_t *iv ) const -{ - return getReverseEncryption() ? - _encodePath( path, iv ) : - _decodePath( path, iv ); -} - - -int NameIO::encodeName( const char *input, int length, char *output ) const -{ - return encodeName( input, length, (uint64_t*)0, output ); +std::string NameIO::_decodePath(const char *cipherPath, uint64_t *iv) const { + // if chaining is not enabled, then the iv pointer is not used.. + if (!chainedNameIV) iv = 0; + return recodePath(cipherPath, &NameIO::maxDecodedNameLen, &NameIO::decodeName, + iv); } -int NameIO::decodeName( const char *input, int length, char *output ) const -{ - return decodeName( input, length, (uint64_t*)0, output ); +std::string NameIO::encodePath(const char *path, uint64_t *iv) const { + return getReverseEncryption() ? _decodePath(path, iv) : _encodePath(path, iv); } -std::string NameIO::_encodeName( const char *plaintextName, int length ) const -{ - int approxLen = maxEncodedNameLen( length ); +std::string NameIO::decodePath(const char *path, uint64_t *iv) const { + return getReverseEncryption() ? _encodePath(path, iv) : _decodePath(path, iv); +} - BUFFER_INIT( codeBuf, 32, (unsigned int)approxLen+1 ); +int NameIO::encodeName(const char *input, int length, char *output) const { + return encodeName(input, length, (uint64_t *)0, output); +} + +int NameIO::decodeName(const char *input, int length, char *output) const { + return decodeName(input, length, (uint64_t *)0, output); +} + +std::string NameIO::_encodeName(const char *plaintextName, int length) const { + int approxLen = maxEncodedNameLen(length); + + BUFFER_INIT(codeBuf, 32, (unsigned int)approxLen + 1); // code the name - int codedLen = encodeName( plaintextName, length, 0, codeBuf ); - rAssert( codedLen <= approxLen ); - rAssert( codeBuf[codedLen] == '\0' ); + int codedLen = encodeName(plaintextName, length, 0, codeBuf); + rAssert(codedLen <= approxLen); + rAssert(codeBuf[codedLen] == '\0'); // append result to string - std::string result = (char*)codeBuf; + std::string result = (char *)codeBuf; - BUFFER_RESET( codeBuf ); + BUFFER_RESET(codeBuf); return result; } -std::string NameIO::_decodeName( const char *encodedName, int length ) const -{ - int approxLen = maxDecodedNameLen( length ); +std::string NameIO::_decodeName(const char *encodedName, int length) const { + int approxLen = maxDecodedNameLen(length); - BUFFER_INIT( codeBuf, 32, (unsigned int)approxLen+1 ); + BUFFER_INIT(codeBuf, 32, (unsigned int)approxLen + 1); // code the name - int codedLen = decodeName( encodedName, length, 0, codeBuf ); - rAssert( codedLen <= approxLen ); - rAssert( codeBuf[codedLen] == '\0' ); + int codedLen = decodeName(encodedName, length, 0, codeBuf); + rAssert(codedLen <= approxLen); + rAssert(codeBuf[codedLen] == '\0'); // append result to string - std::string result = (char*)codeBuf; + std::string result = (char *)codeBuf; - BUFFER_RESET( codeBuf ); + BUFFER_RESET(codeBuf); return result; } -std::string NameIO::encodeName( const char *path, int length ) const -{ - return getReverseEncryption() ? - _decodeName( path, length ) : - _encodeName( path, length ); +std::string NameIO::encodeName(const char *path, int length) const { + return getReverseEncryption() ? _decodeName(path, length) + : _encodeName(path, length); } -std::string NameIO::decodeName( const char *path, int length ) const -{ - return getReverseEncryption() ? - _encodeName( path, length ) : - _decodeName( path, length ); +std::string NameIO::decodeName(const char *path, int length) const { + return getReverseEncryption() ? _encodeName(path, length) + : _decodeName(path, length); } } // namespace encfs - diff --git a/fs/NameIO.h b/fs/NameIO.h index 548df9e..5f3e11c 100644 --- a/fs/NameIO.h +++ b/fs/NameIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -33,14 +33,12 @@ namespace encfs { class CipherV1; -class NameIO -{ +class NameIO { public: - typedef shared_ptr (*Constructor)(const Interface &iface, - const shared_ptr &cipher); + typedef shared_ptr(*Constructor)(const Interface &iface, + const shared_ptr &cipher); - struct Algorithm - { + struct Algorithm { std::string name; std::string description; Interface iface; @@ -48,72 +46,65 @@ class NameIO }; typedef std::list AlgorithmList; - static AlgorithmList GetAlgorithmList( bool includeHidden = false ); + static AlgorithmList GetAlgorithmList(bool includeHidden = false); static shared_ptr New(const Interface &iface, const shared_ptr &cipher); static shared_ptr New(const std::string &name, const shared_ptr &cipher); - static bool Register( const char *name, const char *description, - const Interface &iface, Constructor constructor, - bool needsStreamMode, - bool hidden = false); - + static bool Register(const char *name, const char *description, + const Interface &iface, Constructor constructor, + bool needsStreamMode, bool hidden = false); NameIO(); virtual ~NameIO(); - virtual Interface interface() const =0; + virtual Interface interface() const = 0; - void setChainedNameIV( bool enable ); + void setChainedNameIV(bool enable); bool getChainedNameIV() const; - void setReverseEncryption( bool enable ); + void setReverseEncryption(bool enable); bool getReverseEncryption() const; - std::string encodePath( const char *plaintextPath ) const; - std::string decodePath( const char *encodedPath ) const; + std::string encodePath(const char *plaintextPath) const; + std::string decodePath(const char *encodedPath) const; - std::string encodePath( const char *plaintextPath, uint64_t *iv ) const; - std::string decodePath( const char *encodedPath, uint64_t *iv ) const; + std::string encodePath(const char *plaintextPath, uint64_t *iv) const; + std::string decodePath(const char *encodedPath, uint64_t *iv) const; - virtual int maxEncodedNameLen( int plaintextNameLen ) const =0; - virtual int maxDecodedNameLen( int encodedNameLen ) const =0; + virtual int maxEncodedNameLen(int plaintextNameLen) const = 0; + virtual int maxDecodedNameLen(int encodedNameLen) const = 0; - std::string encodeName( const char *plaintextName, int length ) const; - std::string decodeName( const char *encodedName, int length ) const; + std::string encodeName(const char *plaintextName, int length) const; + std::string decodeName(const char *encodedName, int length) const; - protected: - virtual int encodeName( const char *plaintextName, int length, - char *encodedName ) const; - virtual int decodeName( const char *encodedName, int length, - char *plaintextName ) const; - - virtual int encodeName( const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const =0; - virtual int decodeName( const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const =0; + protected: + virtual int encodeName(const char *plaintextName, int length, + char *encodedName) const; + virtual int decodeName(const char *encodedName, int length, + char *plaintextName) const; + virtual int encodeName(const char *plaintextName, int length, uint64_t *iv, + char *encodedName) const = 0; + virtual int decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const = 0; private: - - std::string recodePath( const char *path, - int (NameIO::*codingLen)(int) const, - int (NameIO::*codingFunc)(const char *, int, + std::string recodePath(const char *path, int (NameIO::*codingLen)(int) const, + int (NameIO::*codingFunc)(const char *, int, uint64_t *, char *) const, - uint64_t *iv ) const; + uint64_t *iv) const; - std::string _encodePath( const char *plaintextPath, uint64_t *iv ) const; - std::string _decodePath( const char *encodedPath, uint64_t *iv ) const; - std::string _encodeName( const char *plaintextName, int length ) const; - std::string _decodeName( const char *encodedName, int length ) const; + std::string _encodePath(const char *plaintextPath, uint64_t *iv) const; + std::string _decodePath(const char *encodedPath, uint64_t *iv) const; + std::string _encodeName(const char *plaintextName, int length) const; + std::string _decodeName(const char *encodedName, int length) const; bool chainedNameIV; bool reverseEncryption; }; - - /* Helper macros for creating temporary buffers with an optimization that below a given size (OptimizedSize) is allocated on the stack, and when a @@ -121,23 +112,22 @@ class NameIO BUFFER_RESET should be called for the same name as BUFFER_INIT */ -#define BUFFER_INIT( Name, OptimizedSize, Size ) \ - char Name ## _Raw [ OptimizedSize ]; \ - char *Name = Name ## _Raw; \ - if( sizeof(Name ## _Raw) < Size ) { \ - Name = new char[ Size ];\ - } \ - memset( Name, 0, Size ) +#define BUFFER_INIT(Name, OptimizedSize, Size) \ + char Name##_Raw[OptimizedSize]; \ + char *Name = Name##_Raw; \ + if (sizeof(Name##_Raw) < Size) { \ + Name = new char[Size]; \ + } \ + memset(Name, 0, Size) -#define BUFFER_RESET( Name ) \ - do { \ - if( Name != Name ## _Raw ) { \ - delete[] Name; \ - Name = Name ## _Raw; \ - } \ - } while(0) +#define BUFFER_RESET(Name) \ + do { \ + if (Name != Name##_Raw) { \ + delete[] Name; \ + Name = Name##_Raw; \ + } \ + } while (0) } // namespace encfs #endif - diff --git a/fs/NullNameIO.cpp b/fs/NullNameIO.cpp index 0b78e64..79cc9f1 100644 --- a/fs/NullNameIO.cpp +++ b/fs/NullNameIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -26,63 +26,43 @@ namespace encfs { -static shared_ptr NewNNIO( const Interface &, - const shared_ptr & ) -{ - return shared_ptr( new NullNameIO() ); +static shared_ptr NewNNIO(const Interface &, + const shared_ptr &) { + return shared_ptr(new NullNameIO()); } static Interface NNIOIface = makeInterface("nameio/null", 1, 0, 0); -static bool NullNameIO_registered = NameIO::Register("Null", - "No encryption of filenames", NNIOIface, NewNNIO, false); +static bool NullNameIO_registered = NameIO::Register( + "Null", "No encryption of filenames", NNIOIface, NewNNIO, false); -NullNameIO::NullNameIO( ) -{ -} +NullNameIO::NullNameIO() {} -NullNameIO::~NullNameIO() -{ -} +NullNameIO::~NullNameIO() {} -Interface NullNameIO::interface() const -{ - return NNIOIface; -} +Interface NullNameIO::interface() const { return NNIOIface; } -Interface NullNameIO::CurrentInterface() -{ - return NNIOIface; -} +Interface NullNameIO::CurrentInterface() { return NNIOIface; } - -int NullNameIO::maxEncodedNameLen( int plaintextNameLen ) const -{ +int NullNameIO::maxEncodedNameLen(int plaintextNameLen) const { return plaintextNameLen; } -int NullNameIO::maxDecodedNameLen( int encodedNameLen ) const -{ +int NullNameIO::maxDecodedNameLen(int encodedNameLen) const { return encodedNameLen; } -int NullNameIO::encodeName( const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const -{ - memcpy( encodedName, plaintextName, length ); +int NullNameIO::encodeName(const char *plaintextName, int length, uint64_t *iv, + char *encodedName) const { + memcpy(encodedName, plaintextName, length); return length; } -int NullNameIO::decodeName( const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const -{ - memcpy( plaintextName, encodedName, length ); +int NullNameIO::decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const { + memcpy(plaintextName, encodedName, length); return length; } -bool NullNameIO::Enabled() -{ - return true; -} +bool NullNameIO::Enabled() { return true; } } // namespace encfs - diff --git a/fs/NullNameIO.h b/fs/NullNameIO.h index 3f1f1f1..acdbb12 100644 --- a/fs/NullNameIO.h +++ b/fs/NullNameIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -25,31 +25,31 @@ namespace encfs { -class NullNameIO : public NameIO -{ -public: - static Interface CurrentInterface(); +class NullNameIO : public NameIO { + public: + static Interface CurrentInterface(); - NullNameIO( ); + NullNameIO(); - virtual ~NullNameIO(); + virtual ~NullNameIO(); - virtual Interface interface() const; + virtual Interface interface() const; - virtual int maxEncodedNameLen( int plaintextNameLen ) const; - virtual int maxDecodedNameLen( int encodedNameLen ) const; + virtual int maxEncodedNameLen(int plaintextNameLen) const; + virtual int maxDecodedNameLen(int encodedNameLen) const; - // hack to help with static builds - static bool Enabled(); -protected: - virtual int encodeName( const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const; - virtual int decodeName( const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const; -private: + // hack to help with static builds + static bool Enabled(); + + protected: + virtual int encodeName(const char *plaintextName, int length, uint64_t *iv, + char *encodedName) const; + virtual int decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const; + + private: }; } // namespace encfs #endif - diff --git a/fs/RawFileIO.cpp b/fs/RawFileIO.cpp index fa76676..d4d129e 100644 --- a/fs/RawFileIO.cpp +++ b/fs/RawFileIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -19,7 +19,7 @@ */ #ifdef linux -#define _XOPEN_SOURCE 500 // pick up pread , pwrite +#define _XOPEN_SOURCE 500 // pick up pread , pwrite #endif #include @@ -39,57 +39,41 @@ namespace encfs { static Interface RawFileIO_iface = makeInterface("FileIO/Raw", 1, 0, 0); -FileIO *NewRawFileIO( const Interface &iface ) -{ - (void)iface; - return new RawFileIO(); +FileIO *NewRawFileIO(const Interface &iface) { + (void)iface; + return new RawFileIO(); } -inline void swap( int &x, int &y ) -{ - int tmp = x; - x = y; - y = tmp; +inline void swap(int &x, int &y) { + int tmp = x; + x = y; + y = tmp; } -RawFileIO::RawFileIO( ) - : knownSize( false ) - , fileSize(0) - , fd( -1 ) - , oldfd( -1 ) - , canWrite( false ) -{ -} +RawFileIO::RawFileIO() + : knownSize(false), fileSize(0), fd(-1), oldfd(-1), canWrite(false) {} -RawFileIO::RawFileIO( const std::string &fileName ) - : name( fileName ) - , knownSize( false ) - , fileSize( 0 ) - , fd( -1 ) - , oldfd( -1 ) - , canWrite( false ) -{ -} +RawFileIO::RawFileIO(const std::string &fileName) + : name(fileName), + knownSize(false), + fileSize(0), + fd(-1), + oldfd(-1), + canWrite(false) {} -RawFileIO::~RawFileIO() -{ +RawFileIO::~RawFileIO() { int _fd = -1; int _oldfd = -1; - swap( _fd, fd ); - swap( _oldfd, oldfd ); + swap(_fd, fd); + swap(_oldfd, oldfd); - if( _oldfd != -1 ) - close( _oldfd ); + if (_oldfd != -1) close(_oldfd); - if( _fd != -1 ) - close( _fd ); + if (_fd != -1) close(_fd); } -Interface RawFileIO::interface() const -{ - return RawFileIO_iface; -} +Interface RawFileIO::interface() const { return RawFileIO_iface; } /* Workaround for opening a file for write when permissions don't allow. @@ -98,19 +82,16 @@ Interface RawFileIO::interface() const be called with a lock around it so that there won't be a race condition with calls to lstat picking up the wrong permissions. */ -static int open_readonly_workaround(const char *path, int flags) -{ +static int open_readonly_workaround(const char *path, int flags) { int fd = -1; struct stat stbuf; memset(&stbuf, 0, sizeof(struct stat)); - if(lstat( path, &stbuf ) != -1) - { + if (lstat(path, &stbuf) != -1) { // make sure user has read/write permission.. - chmod( path , stbuf.st_mode | 0600 ); - fd = ::open( path , flags ); - chmod( path , stbuf.st_mode ); - } else - { + chmod(path, stbuf.st_mode | 0600); + fd = ::open(path, flags); + chmod(path, stbuf.st_mode); + } else { LOG(INFO) << "can't stat file " << path; } @@ -126,48 +107,40 @@ static int open_readonly_workaround(const char *path, int flags) - Also keep the O_LARGEFILE flag, in case the underlying filesystem needs it.. */ -int RawFileIO::open(int flags) -{ +int RawFileIO::open(int flags) { bool requestWrite = ((flags & O_RDWR) || (flags & O_WRONLY)); - VLOG(1) << "open call for " - << (requestWrite ? "writable" : "read only") - << " file"; + VLOG(1) << "open call for " << (requestWrite ? "writable" : "read only") + << " file"; int result = 0; // if we have a descriptor and it is writable, or we don't need writable.. - if((fd >= 0) && (canWrite || !requestWrite)) - { + if ((fd >= 0) && (canWrite || !requestWrite)) { VLOG(1) << "using existing file descriptor"; - result = fd; // success - } else - { + result = fd; // success + } else { int finalFlags = requestWrite ? O_RDWR : O_RDONLY; #if defined(O_LARGEFILE) - if( flags & O_LARGEFILE ) - finalFlags |= O_LARGEFILE; + if (flags & O_LARGEFILE) finalFlags |= O_LARGEFILE; #else #warning O_LARGEFILE not supported #endif - int newFd = ::open( name.c_str(), finalFlags ); + int newFd = ::open(name.c_str(), finalFlags); VLOG(1) << "open file with flags " << finalFlags << ", result = " << newFd; - if((newFd == -1) && (errno == EACCES)) - { + if ((newFd == -1) && (errno == EACCES)) { VLOG(1) << "using readonly workaround for open"; - newFd = open_readonly_workaround( name.c_str(), finalFlags ); + newFd = open_readonly_workaround(name.c_str(), finalFlags); } - if(newFd >= 0) - { - if(oldfd >= 0) - { - LOG(ERROR) << "leaking FD?: oldfd = " - << oldfd << ", fd = " << fd << ", newfd = " << newFd; + if (newFd >= 0) { + if (oldfd >= 0) { + LOG(ERROR) << "leaking FD?: oldfd = " << oldfd << ", fd = " << fd + << ", newfd = " << newFd; } // the old fd might still be in use, so just keep it around for @@ -175,8 +148,7 @@ int RawFileIO::open(int flags) canWrite = requestWrite; oldfd = fd; result = fd = newFd; - } else - { + } else { result = -errno; LOG(INFO) << "::open error: " << strerror(errno); } @@ -187,68 +159,53 @@ int RawFileIO::open(int flags) return result; } -int RawFileIO::getAttr( struct stat *stbuf ) const -{ - int res = lstat( name.c_str(), stbuf ); +int RawFileIO::getAttr(struct stat *stbuf) const { + int res = lstat(name.c_str(), stbuf); int eno = errno; - LOG_IF(INFO, res < 0) << "getAttr error on " << name - << ": " << strerror( eno ); + LOG_IF(INFO, res < 0) << "getAttr error on " << name << ": " << strerror(eno); - return ( res < 0 ) ? -eno : 0; + return (res < 0) ? -eno : 0; } -void RawFileIO::setFileName( const char *fileName ) -{ - name = fileName; -} +void RawFileIO::setFileName(const char *fileName) { name = fileName; } -const char *RawFileIO::getFileName() const -{ - return name.c_str(); -} +const char *RawFileIO::getFileName() const { return name.c_str(); } -off_t RawFileIO::getSize() const -{ - if(!knownSize) - { +off_t RawFileIO::getSize() const { + if (!knownSize) { struct stat stbuf; - memset( &stbuf, 0, sizeof( struct stat )); - int res = lstat( name.c_str(), &stbuf ); + memset(&stbuf, 0, sizeof(struct stat)); + int res = lstat(name.c_str(), &stbuf); - if(res == 0) - { + if (res == 0) { fileSize = stbuf.st_size; knownSize = true; return fileSize; } else return -1; - } else - { + } else { return fileSize; } } -ssize_t RawFileIO::read( const IORequest &req ) const -{ - rAssert( fd >= 0 ); +ssize_t RawFileIO::read(const IORequest &req) const { + rAssert(fd >= 0); VLOG(2) << "Read " << req.dataLen << " bytes from offset " << req.offset; - ssize_t readSize = pread( fd, req.data, req.dataLen, req.offset ); + ssize_t readSize = pread(fd, req.data, req.dataLen, req.offset); - if(readSize < 0) - { - LOG(INFO) << "read failed at offset " << req.offset - << " for " << req.dataLen << " bytes: " << strerror(errno); + if (readSize < 0) { + LOG(INFO) << "read failed at offset " << req.offset << " for " + << req.dataLen << " bytes: " << strerror(errno); } return readSize; } -bool RawFileIO::write( const IORequest &req ) -{ - rAssert( fd >= 0 ); - rAssert( true == canWrite ); +bool RawFileIO::write(const IORequest &req) { + rAssert(fd >= 0); + rAssert(true == canWrite); VLOG(2) << "Write " << req.dataLen << " bytes to offset " << req.offset; @@ -257,65 +214,55 @@ bool RawFileIO::write( const IORequest &req ) ssize_t bytes = req.dataLen; off_t offset = req.offset; - while( bytes && retrys > 0 ) - { - ssize_t writeSize = ::pwrite( fd, buf, bytes, offset ); + while (bytes && retrys > 0) { + ssize_t writeSize = ::pwrite(fd, buf, bytes, offset); - if( writeSize < 0 ) - { + if (writeSize < 0) { knownSize = false; - LOG(INFO) << "write failed at offset " << offset << " for " - << bytes << " bytes: " << strerror(errno); + LOG(INFO) << "write failed at offset " << offset << " for " << bytes + << " bytes: " << strerror(errno); return false; } bytes -= writeSize; offset += writeSize; - buf = (void*)((char*)buf + writeSize); + buf = (void *)((char *)buf + writeSize); --retrys; } - if(bytes != 0) - { - LOG(ERROR) << "Write error: wrote " << (req.dataLen-bytes) - << " bytes of " << req.dataLen << ", max retries reached"; + if (bytes != 0) { + LOG(ERROR) << "Write error: wrote " << (req.dataLen - bytes) << " bytes of " + << req.dataLen << ", max retries reached"; knownSize = false; return false; - } else - { - if(knownSize) - { + } else { + if (knownSize) { off_t last = req.offset + req.dataLen; - if(last > fileSize) - fileSize = last; + if (last > fileSize) fileSize = last; } return true; } } -int RawFileIO::truncate( off_t size ) -{ +int RawFileIO::truncate(off_t size) { int res; - if(fd >= 0 && canWrite) - { - res = ::ftruncate( fd, size ); + if (fd >= 0 && canWrite) { + res = ::ftruncate(fd, size); #ifndef __FreeBSD__ - ::fdatasync( fd ); + ::fdatasync(fd); #endif } else - res = ::truncate( name.c_str(), size ); + res = ::truncate(name.c_str(), size); - if(res < 0) - { + if (res < 0) { int eno = errno; - LOG(INFO) << "truncate failed for " << name - << " (" << fd << ") size " << size << ", error " << strerror(eno); + LOG(INFO) << "truncate failed for " << name << " (" << fd << ") size " + << size << ", error " << strerror(eno); res = -eno; knownSize = false; - } else - { + } else { res = 0; fileSize = size; knownSize = true; @@ -324,10 +271,6 @@ int RawFileIO::truncate( off_t size ) return res; } -bool RawFileIO::isWritable() const -{ - return canWrite; -} +bool RawFileIO::isWritable() const { return canWrite; } } // namespace encfs - diff --git a/fs/RawFileIO.h b/fs/RawFileIO.h index dc7c7ab..97ead7f 100644 --- a/fs/RawFileIO.h +++ b/fs/RawFileIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -27,42 +27,40 @@ namespace encfs { -class RawFileIO : public FileIO -{ -public: - RawFileIO(); - RawFileIO( const std::string &fileName ); - virtual ~RawFileIO(); +class RawFileIO : public FileIO { + public: + RawFileIO(); + RawFileIO(const std::string &fileName); + virtual ~RawFileIO(); - virtual Interface interface() const; + virtual Interface interface() const; - virtual void setFileName( const char *fileName ); - virtual const char *getFileName() const; + virtual void setFileName(const char *fileName); + virtual const char *getFileName() const; - virtual int open( int flags ); - - virtual int getAttr( struct stat *stbuf ) const; - virtual off_t getSize() const; + virtual int open(int flags); - virtual ssize_t read( const IORequest & req ) const; - virtual bool write( const IORequest &req ); + virtual int getAttr(struct stat *stbuf) const; + virtual off_t getSize() const; - virtual int truncate( off_t size ); + virtual ssize_t read(const IORequest &req) const; + virtual bool write(const IORequest &req); - virtual bool isWritable() const; -protected: + virtual int truncate(off_t size); - std::string name; + virtual bool isWritable() const; - mutable bool knownSize; - mutable off_t fileSize; + protected: + std::string name; - int fd; - int oldfd; - bool canWrite; + mutable bool knownSize; + mutable off_t fileSize; + + int fd; + int oldfd; + bool canWrite; }; } // namespace encfs #endif - diff --git a/fs/StreamNameIO.cpp b/fs/StreamNameIO.cpp index 77968cf..f92acc6 100644 --- a/fs/StreamNameIO.cpp +++ b/fs/StreamNameIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -30,17 +30,15 @@ namespace encfs { -static shared_ptr NewStreamNameIO( const Interface &iface, - const shared_ptr &cipher ) -{ - return shared_ptr( new StreamNameIO( iface, cipher ) ); +static shared_ptr NewStreamNameIO(const Interface &iface, + const shared_ptr &cipher) { + return shared_ptr(new StreamNameIO(iface, cipher)); } -static bool StreamIO_registered = NameIO::Register("Stream", +static bool StreamIO_registered = NameIO::Register( + "Stream", gettext_noop("Stream encoding, keeps filenames as short as possible"), - StreamNameIO::CurrentInterface(), - NewStreamNameIO, true); - + StreamNameIO::CurrentInterface(), NewStreamNameIO, true); /* - Version 0.1 is for EncFS 0.x support. The difference to 1.0 is that 0.x @@ -63,144 +61,117 @@ static bool StreamIO_registered = NameIO::Register("Stream", - Version 2.1 adds support for version 0 for EncFS 0.x compatibility. */ -Interface StreamNameIO::CurrentInterface() -{ +Interface StreamNameIO::CurrentInterface() { // implement major version 2, 1, and 0 return makeInterface("nameio/stream", 2, 1, 2); } -StreamNameIO::StreamNameIO( const Interface &iface, - const shared_ptr &cipher ) - : _interface( iface.major() ) - , _cipher( cipher ) -{ +StreamNameIO::StreamNameIO(const Interface &iface, + const shared_ptr &cipher) + : _interface(iface.major()), _cipher(cipher) {} -} +StreamNameIO::~StreamNameIO() {} -StreamNameIO::~StreamNameIO() -{ -} +Interface StreamNameIO::interface() const { return CurrentInterface(); } -Interface StreamNameIO::interface() const -{ - return CurrentInterface(); -} - -int StreamNameIO::maxEncodedNameLen( int plaintextStreamLen ) const -{ +int StreamNameIO::maxEncodedNameLen(int plaintextStreamLen) const { int encodedStreamLen = 2 + plaintextStreamLen; - return B256ToB64Bytes( encodedStreamLen ); + return B256ToB64Bytes(encodedStreamLen); } -int StreamNameIO::maxDecodedNameLen( int encodedStreamLen ) const -{ - int decLen256 = B64ToB256Bytes( encodedStreamLen ); +int StreamNameIO::maxDecodedNameLen(int encodedStreamLen) const { + int decLen256 = B64ToB256Bytes(encodedStreamLen); return decLen256 - 2; } -int StreamNameIO::encodeName( const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const -{ +int StreamNameIO::encodeName(const char *plaintextName, int length, + uint64_t *iv, char *encodedName) const { uint64_t tmpIV = 0; - if( iv && _interface >= 2 ) - tmpIV = *iv; + if (iv && _interface >= 2) tmpIV = *iv; unsigned int mac = _cipher->reduceMac16( - _cipher->MAC_64((const byte *)plaintextName, length, iv )); + _cipher->MAC_64((const byte *)plaintextName, length, iv)); // add on checksum bytes unsigned char *encodeBegin; - if(_interface >= 1) - { + if (_interface >= 1) { // current versions store the checksum at the beginning encodedName[0] = (mac >> 8) & 0xff; - encodedName[1] = (mac ) & 0xff; - encodeBegin = (unsigned char *)encodedName+2; - } else - { + encodedName[1] = (mac) & 0xff; + encodeBegin = (unsigned char *)encodedName + 2; + } else { // encfs 0.x stored checksums at the end. encodedName[length] = (mac >> 8) & 0xff; - encodedName[length+1] = (mac ) & 0xff; + encodedName[length + 1] = (mac) & 0xff; encodeBegin = (unsigned char *)encodedName; } // stream encode the plaintext bytes - memcpy( encodeBegin, plaintextName, length ); - _cipher->streamEncode( encodeBegin, length, (uint64_t)mac ^ tmpIV); + memcpy(encodeBegin, plaintextName, length); + _cipher->streamEncode(encodeBegin, length, (uint64_t)mac ^ tmpIV); // convert the entire thing to base 64 ascii.. int encodedStreamLen = length + 2; - int encLen64 = B256ToB64Bytes( encodedStreamLen ); + int encLen64 = B256ToB64Bytes(encodedStreamLen); - changeBase2Inline( (unsigned char *)encodedName, encodedStreamLen, - 8, 6, true ); - B64ToAscii( (unsigned char *)encodedName, encLen64 ); + changeBase2Inline((unsigned char *)encodedName, encodedStreamLen, 8, 6, true); + B64ToAscii((unsigned char *)encodedName, encLen64); return encLen64; } -int StreamNameIO::decodeName( const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const -{ +int StreamNameIO::decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const { rAssert(length > 2); - int decLen256 = B64ToB256Bytes( length ); + int decLen256 = B64ToB256Bytes(length); int decodedStreamLen = decLen256 - 2; - if(decodedStreamLen <= 0) - throw Error("Filename too small to decode"); + if (decodedStreamLen <= 0) throw Error("Filename too small to decode"); - BUFFER_INIT( tmpBuf, 32, (unsigned int)length ); + BUFFER_INIT(tmpBuf, 32, (unsigned int)length); // decode into tmpBuf, because this step produces more data then we can fit // into the result buffer.. - AsciiToB64( (unsigned char *)tmpBuf, (unsigned char *)encodedName, length ); + AsciiToB64((unsigned char *)tmpBuf, (unsigned char *)encodedName, length); changeBase2Inline((unsigned char *)tmpBuf, length, 6, 8, false); // pull out the checksum value which is used as an initialization vector uint64_t tmpIV = 0; unsigned int mac; - if(_interface >= 1) - { + if (_interface >= 1) { // current versions store the checksum at the beginning - mac = ((unsigned int)((unsigned char)tmpBuf[0])) << 8 - | ((unsigned int)((unsigned char)tmpBuf[1])); + mac = ((unsigned int)((unsigned char)tmpBuf[0])) << 8 | + ((unsigned int)((unsigned char)tmpBuf[1])); // version 2 adds support for IV chaining.. - if( iv && _interface >= 2 ) - tmpIV = *iv; + if (iv && _interface >= 2) tmpIV = *iv; - memcpy( plaintextName, tmpBuf+2, decodedStreamLen ); - } else - { + memcpy(plaintextName, tmpBuf + 2, decodedStreamLen); + } else { // encfs 0.x stored checksums at the end. - mac = ((unsigned int)((unsigned char)tmpBuf[decodedStreamLen])) << 8 - | ((unsigned int)((unsigned char)tmpBuf[decodedStreamLen+1])); + mac = ((unsigned int)((unsigned char)tmpBuf[decodedStreamLen])) << 8 | + ((unsigned int)((unsigned char)tmpBuf[decodedStreamLen + 1])); - memcpy( plaintextName, tmpBuf, decodedStreamLen ); + memcpy(plaintextName, tmpBuf, decodedStreamLen); } - _cipher->streamDecode( (unsigned char *)plaintextName, decodedStreamLen, - (uint64_t)mac ^ tmpIV ); + _cipher->streamDecode((unsigned char *)plaintextName, decodedStreamLen, + (uint64_t)mac ^ tmpIV); // compute MAC to check with stored value unsigned int mac2 = _cipher->reduceMac16( _cipher->MAC_64((const byte *)plaintextName, decodedStreamLen, iv)); - BUFFER_RESET( tmpBuf ); - if(mac2 != mac) - { + BUFFER_RESET(tmpBuf); + if (mac2 != mac) { VLOG(1) << "checksum mismatch: expected " << mac << ", got " << mac2 - << "on decode of " << decodedStreamLen << " bytes"; - throw Error( "checksum mismatch in filename decode" ); + << "on decode of " << decodedStreamLen << " bytes"; + throw Error("checksum mismatch in filename decode"); } return decodedStreamLen; } -bool StreamNameIO::Enabled() -{ - return true; -} +bool StreamNameIO::Enabled() { return true; } } // namespace encfs - diff --git a/fs/StreamNameIO.h b/fs/StreamNameIO.h index 60b03de..923ee1c 100644 --- a/fs/StreamNameIO.h +++ b/fs/StreamNameIO.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -27,33 +27,32 @@ namespace encfs { class CipherV1; -class StreamNameIO : public NameIO -{ -public: - static Interface CurrentInterface(); +class StreamNameIO : public NameIO { + public: + static Interface CurrentInterface(); - StreamNameIO( const Interface &iface, - const shared_ptr &cipher); - virtual ~StreamNameIO(); + StreamNameIO(const Interface &iface, const shared_ptr &cipher); + virtual ~StreamNameIO(); - virtual Interface interface() const; + virtual Interface interface() const; - virtual int maxEncodedNameLen( int plaintextNameLen ) const; - virtual int maxDecodedNameLen( int encodedNameLen ) const; + virtual int maxEncodedNameLen(int plaintextNameLen) const; + virtual int maxDecodedNameLen(int encodedNameLen) const; - // hack to help with static builds - static bool Enabled(); -protected: - virtual int encodeName( const char *plaintextName, int length, - uint64_t *iv, char *encodedName ) const; - virtual int decodeName( const char *encodedName, int length, - uint64_t *iv, char *plaintextName ) const; -private: - int _interface; - shared_ptr _cipher; + // hack to help with static builds + static bool Enabled(); + + protected: + virtual int encodeName(const char *plaintextName, int length, uint64_t *iv, + char *encodedName) const; + virtual int decodeName(const char *encodedName, int length, uint64_t *iv, + char *plaintextName) const; + + private: + int _interface; + shared_ptr _cipher; }; } // namespace encfs #endif - diff --git a/fs/checkops.cpp b/fs/checkops.cpp index 48f5b9c..cf8ed02 100644 --- a/fs/checkops.cpp +++ b/fs/checkops.cpp @@ -54,47 +54,40 @@ namespace encfs { const int FSBlockSize = 256; -static -int checkErrorPropogation( const shared_ptr &cipher, - int size, int byteToChange ) -{ +static int checkErrorPropogation(const shared_ptr &cipher, int size, + int byteToChange) { MemBlock orig; orig.allocate(size); MemBlock data; data.allocate(size); - for(int i=0; istreamEncode( data.data, size, 0 ); + if (size != FSBlockSize) + cipher->streamEncode(data.data, size, 0); else - cipher->blockEncode( data.data, size, 0 ); + cipher->blockEncode(data.data, size, 0); // intoduce an error in the encoded data, so we can check error propogation - if(byteToChange >= 0 && byteToChange < size) - { + if (byteToChange >= 0 && byteToChange < size) { unsigned char previousValue = data.data[byteToChange]; - do - { + do { data.data[byteToChange] = rand(); - } while(data.data[byteToChange] == previousValue); + } while (data.data[byteToChange] == previousValue); } - if(size != FSBlockSize) - cipher->streamDecode( data.data, size, 0 ); + if (size != FSBlockSize) + cipher->streamDecode(data.data, size, 0); else - cipher->blockDecode( data.data, size, 0 ); + cipher->blockDecode(data.data, size, 0); int numByteErrors = 0; - for(int i=0; i &cipher, const char TEST_ROOTDIR[] = "/foo"; -static -bool testNameCoding( DirNode &dirNode, bool verbose, - bool collisionTest = false ) -{ +static bool testNameCoding(DirNode &dirNode, bool verbose, + bool collisionTest = false) { // encrypt a name const char *name[] = { - "1234567", - "12345678", - "123456789", - "123456789ABCDEF", - "123456789ABCDEF0", - "123456789ABCDEF01", - "test-name", - "test-name2", - "test", - "../test", - "/foo/bar/blah", - "test-name.21", - "test-name.22", - "test-name.o", - "1.test", - "2.test", - "a/b/c/d", - "a/c/d/e", - "b/c/d/e", - "b/a/c/d", - NULL - }; + "1234567", "12345678", "123456789", + "123456789ABCDEF", "123456789ABCDEF0", "123456789ABCDEF01", + "test-name", "test-name2", "test", + "../test", "/foo/bar/blah", "test-name.21", + "test-name.22", "test-name.o", "1.test", + "2.test", "a/b/c/d", "a/c/d/e", + "b/c/d/e", "b/a/c/d", NULL}; const char **orig = name; - while(*orig) - { - if(verbose) - cerr << " coding name \"" << *orig << "\""; + while (*orig) { + if (verbose) cerr << " coding name \"" << *orig << "\""; - string encName = dirNode.relativeCipherPath( *orig ); + string encName = dirNode.relativeCipherPath(*orig); - if(verbose) - cerr << " -> \"" << encName.c_str() << "\""; + if (verbose) cerr << " -> \"" << encName.c_str() << "\""; // decrypt name - string decName = dirNode.plainPath( encName.c_str() ); + string decName = dirNode.plainPath(encName.c_str()); - if(decName == *orig) - { - if(verbose) - cerr << " OK\n"; - } else - { - if(verbose) - cerr << " FAILED (got " << decName << ")\n"; + if (decName == *orig) { + if (verbose) cerr << " OK\n"; + } else { + if (verbose) cerr << " FAILED (got " << decName << ")\n"; return false; } orig++; } - if (collisionTest) - { + if (collisionTest) { if (verbose) cerr << "Checking for name collections, this will take a while..\n"; // check for collision rate char buf[64]; unordered_set encryptedNames; - for (long i=0; i < 10000000; i++) - { + for (long i = 0; i < 10000000; i++) { snprintf(buf, sizeof(buf), "%li", i); - string encName = dirNode.relativeCipherPath( buf ); + string encName = dirNode.relativeCipherPath(buf); // simulate a case-insisitive filesystem.. std::transform(encName.begin(), encName.end(), encName.begin(), - ::toupper); + ::toupper); if (encryptedNames.insert(encName).second == false) { cerr << "collision detected after " << i << " iterations"; @@ -185,60 +152,51 @@ bool testNameCoding( DirNode &dirNode, bool verbose, return true; } -bool runTests(const shared_ptr &cipher, bool verbose) -{ +bool runTests(const shared_ptr &cipher, bool verbose) { // create a random key - if(verbose) + if (verbose) cerr << "Generating new key, output will be different on each run\n\n"; CipherKey key = cipher->newRandomKey(); - if(verbose) - cerr << "Testing key save / restore :"; + if (verbose) cerr << "Testing key save / restore :"; { CipherKey encodingKey = cipher->newRandomKey(); int encodedKeySize = cipher->encodedKeySize(); - unsigned char *keyBuf = new unsigned char [ encodedKeySize ]; + unsigned char *keyBuf = new unsigned char[encodedKeySize]; cipher->setKey(encodingKey); - cipher->writeKey( key, keyBuf ); - CipherKey key2 = cipher->readKey( keyBuf, true ); + cipher->writeKey(key, keyBuf); + CipherKey key2 = cipher->readKey(keyBuf, true); delete[] keyBuf; - if(!key2.valid()) - { - if(verbose) - cerr << " FAILED (decode error)\n"; + if (!key2.valid()) { + if (verbose) cerr << " FAILED (decode error)\n"; return false; } - if(key == key2) - { - if(verbose) - cerr << " OK\n"; - } else - { - if(verbose) - cerr << " FAILED\n"; + if (key == key2) { + if (verbose) cerr << " OK\n"; + } else { + if (verbose) cerr << " FAILED\n"; return false; } } - if(verbose) - cerr << "Testing Config interface load / store :"; + if (verbose) cerr << "Testing Config interface load / store :"; { CipherKey encodingKey = cipher->newRandomKey(); int encodedKeySize = cipher->encodedKeySize(); - unsigned char *keyBuf = new unsigned char [ encodedKeySize ]; + unsigned char *keyBuf = new unsigned char[encodedKeySize]; cipher->setKey(encodingKey); - cipher->writeKey( key, keyBuf ); + cipher->writeKey(key, keyBuf); // store in config struct.. EncfsConfig cfg; cfg.mutable_cipher()->MergeFrom(cipher->interface()); EncryptedKey *encryptedKey = cfg.mutable_key(); encryptedKey->set_size(8 * cipher->keySize()); - encryptedKey->set_ciphertext( keyBuf, encodedKeySize ); + encryptedKey->set_ciphertext(keyBuf, encodedKeySize); cfg.set_block_size(FSBlockSize); delete[] keyBuf; @@ -252,27 +210,22 @@ bool runTests(const shared_ptr &cipher, bool verbose) google::protobuf::TextFormat::ParseFromString(data, &cfg2); // check.. - rAssert( implements(cfg.cipher(),cfg2.cipher()) ); - rAssert( cfg.key().size() == cfg2.key().size() ); - rAssert( cfg.block_size() == cfg2.block_size() ); + rAssert(implements(cfg.cipher(), cfg2.cipher())); + rAssert(cfg.key().size() == cfg2.key().size()); + rAssert(cfg.block_size() == cfg2.block_size()); // try decoding key.. - CipherKey key2 = cipher->readKey( (unsigned char *)cfg2.key().ciphertext().data(), true ); - if(!key2.valid()) - { - if(verbose) - cerr << " FAILED (decode error)\n"; + CipherKey key2 = + cipher->readKey((unsigned char *)cfg2.key().ciphertext().data(), true); + if (!key2.valid()) { + if (verbose) cerr << " FAILED (decode error)\n"; return false; } - if(key == key2) - { - if(verbose) - cerr << " OK\n"; - } else - { - if(verbose) - cerr << " FAILED\n"; + if (key == key2) { + if (verbose) cerr << " OK\n"; + } else { + if (verbose) cerr << " FAILED\n"; return false; } } @@ -285,175 +238,145 @@ bool runTests(const shared_ptr &cipher, bool verbose) fsCfg->opts.reset(new EncFS_Opts); cipher->setKey(key); - if(verbose) + if (verbose) cerr << "Testing name encode/decode (stream coding w/ IV chaining)\n"; { fsCfg->opts->idleTracking = false; fsCfg->config->set_unique_iv(false); - fsCfg->nameCoding.reset( new StreamNameIO( - StreamNameIO::CurrentInterface(), cipher) ); - fsCfg->nameCoding->setChainedNameIV( true ); + fsCfg->nameCoding.reset( + new StreamNameIO(StreamNameIO::CurrentInterface(), cipher)); + fsCfg->nameCoding->setChainedNameIV(true); - DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg ); + DirNode dirNode(NULL, TEST_ROOTDIR, fsCfg); - if(!testNameCoding( dirNode, verbose )) - return false; + if (!testNameCoding(dirNode, verbose)) return false; } - if(verbose) + if (verbose) cerr << "Testing name encode/decode (block coding w/ IV chaining)\n"; { fsCfg->opts->idleTracking = false; fsCfg->config->set_unique_iv(false); - fsCfg->nameCoding.reset( new BlockNameIO( - BlockNameIO::CurrentInterface(), cipher) ); - fsCfg->nameCoding->setChainedNameIV( true ); + fsCfg->nameCoding.reset( + new BlockNameIO(BlockNameIO::CurrentInterface(), cipher)); + fsCfg->nameCoding->setChainedNameIV(true); - DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg ); + DirNode dirNode(NULL, TEST_ROOTDIR, fsCfg); - if(!testNameCoding( dirNode, verbose )) - return false; + if (!testNameCoding(dirNode, verbose)) return false; } - if(verbose) - cerr << "Testing name encode/decode (block coding w/ IV chaining, base32)\n"; + if (verbose) + cerr + << "Testing name encode/decode (block coding w/ IV chaining, base32)\n"; { fsCfg->opts->idleTracking = false; fsCfg->config->set_unique_iv(false); - fsCfg->nameCoding.reset( new BlockNameIO( - BlockNameIO::CurrentInterface(), cipher) ); - fsCfg->nameCoding->setChainedNameIV( true ); + fsCfg->nameCoding.reset( + new BlockNameIO(BlockNameIO::CurrentInterface(), cipher)); + fsCfg->nameCoding->setChainedNameIV(true); - DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg ); + DirNode dirNode(NULL, TEST_ROOTDIR, fsCfg); - if(!testNameCoding( dirNode, verbose )) - return false; + if (!testNameCoding(dirNode, verbose)) return false; } - if(!verbose) - { + if (!verbose) { { // test stream mode, this time without IV chaining - fsCfg->nameCoding = - shared_ptr( new StreamNameIO( - StreamNameIO::CurrentInterface(), cipher) ); - fsCfg->nameCoding->setChainedNameIV( false ); + fsCfg->nameCoding = shared_ptr( + new StreamNameIO(StreamNameIO::CurrentInterface(), cipher)); + fsCfg->nameCoding->setChainedNameIV(false); - DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg ); + DirNode dirNode(NULL, TEST_ROOTDIR, fsCfg); - if(!testNameCoding( dirNode, verbose )) - return false; + if (!testNameCoding(dirNode, verbose)) return false; } { // test block mode, this time without IV chaining - fsCfg->nameCoding = shared_ptr( new BlockNameIO( - BlockNameIO::CurrentInterface(), cipher) ); - fsCfg->nameCoding->setChainedNameIV( false ); + fsCfg->nameCoding = shared_ptr( + new BlockNameIO(BlockNameIO::CurrentInterface(), cipher)); + fsCfg->nameCoding->setChainedNameIV(false); - DirNode dirNode( NULL, TEST_ROOTDIR, fsCfg ); + DirNode dirNode(NULL, TEST_ROOTDIR, fsCfg); - if(!testNameCoding( dirNode, verbose )) - return false; + if (!testNameCoding(dirNode, verbose)) return false; } } - if(verbose) - cerr << "Testing block encode/decode on full block - "; + if (verbose) cerr << "Testing block encode/decode on full block - "; { - int numErrors = checkErrorPropogation( cipher, - FSBlockSize, -1 ); - if(numErrors) - { - if(verbose) - cerr << " FAILED!\n"; + int numErrors = checkErrorPropogation(cipher, FSBlockSize, -1); + if (numErrors) { + if (verbose) cerr << " FAILED!\n"; return false; - } else - { - if(verbose) - cerr << " OK\n"; + } else { + if (verbose) cerr << " OK\n"; } } - if(verbose) - cerr << "Testing block encode/decode on partial block - "; + if (verbose) cerr << "Testing block encode/decode on partial block - "; { - int numErrors = checkErrorPropogation( cipher, - FSBlockSize-1, -1 ); - if(numErrors) - { - if(verbose) - cerr << " FAILED!\n"; + int numErrors = checkErrorPropogation(cipher, FSBlockSize - 1, -1); + if (numErrors) { + if (verbose) cerr << " FAILED!\n"; return false; - } else - { - if(verbose) - cerr << " OK\n"; + } else { + if (verbose) cerr << " OK\n"; } } - if(verbose) - cerr << "Checking error propogation in partial block:\n"; + if (verbose) cerr << "Checking error propogation in partial block:\n"; { - int minChanges = FSBlockSize-1; + int minChanges = FSBlockSize - 1; int maxChanges = 0; int minAt = 0; int maxAt = 0; - for(int i=0; i maxChanges) - { + if (numErrors > maxChanges) { maxChanges = numErrors; maxAt = i; } } - if(verbose) - { + if (verbose) { cerr << "modification of 1 byte affected between " << minChanges - << " and " << maxChanges << " decoded bytes\n"; - cerr << "minimum change at byte " << minAt - << " and maximum at byte " << maxAt << "\n"; + << " and " << maxChanges << " decoded bytes\n"; + cerr << "minimum change at byte " << minAt << " and maximum at byte " + << maxAt << "\n"; } } - if(verbose) - cerr << "Checking error propogation on full block:\n"; + if (verbose) cerr << "Checking error propogation on full block:\n"; { int minChanges = FSBlockSize; int maxChanges = 0; int minAt = 0; int maxAt = 0; - for(int i=0; i maxChanges) - { + if (numErrors > maxChanges) { maxChanges = numErrors; maxAt = i; } } - if(verbose) - { + if (verbose) { cerr << "modification of 1 byte affected between " << minChanges - << " and " << maxChanges << " decoded bytes\n"; - cerr << "minimum change at byte " << minAt - << " and maximum at byte " << maxAt << "\n"; + << " and " << maxChanges << " decoded bytes\n"; + cerr << "minimum change at byte " << minAt << " and maximum at byte " + << maxAt << "\n"; } } @@ -462,8 +385,7 @@ bool runTests(const shared_ptr &cipher, bool verbose) } // namespace encfs -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { FLAGS_logtostderr = 1; FLAGS_minloglevel = 1; @@ -473,50 +395,42 @@ int main(int argc, char *argv[]) bool isThreaded = false; CipherV1::init(isThreaded); - srand( time(0) ); + srand(time(0)); // get a list of the available algorithms std::list algorithms = - CipherV1::GetAlgorithmList(); + CipherV1::GetAlgorithmList(); std::list::const_iterator it; cerr << "Supported Crypto interfaces:\n"; - for(it = algorithms.begin(); it != algorithms.end(); ++it) - { - cerr << it->name - << " ( " << it->iface.name() << " " - << it->iface.major() << ":" - << it->iface.minor() << ":" - << it->iface.age() << " ) : " << it->description << "\n"; + for (it = algorithms.begin(); it != algorithms.end(); ++it) { + cerr << it->name << " ( " << it->iface.name() << " " << it->iface.major() + << ":" << it->iface.minor() << ":" << it->iface.age() + << " ) : " << it->description << "\n"; cerr << " - key length " << it->keyLength.min() << " to " - << it->keyLength.max() << " , block size " << it->blockSize.min() - << " to " << it->blockSize.max() << "\n"; + << it->keyLength.max() << " , block size " << it->blockSize.min() + << " to " << it->blockSize.max() << "\n"; } cerr << "\n"; cerr << "Testing interfaces\n"; - for(it = algorithms.begin(); it != algorithms.end(); ++it) - { - int blockSize = it->blockSize.closest( 256 ); - for(int keySize = it->keyLength.min(); keySize <= it->keyLength.max(); - keySize += it->keyLength.inc()) - { - cerr << it->name << ", key length " << keySize - << ", block size " << blockSize << ": "; + for (it = algorithms.begin(); it != algorithms.end(); ++it) { + int blockSize = it->blockSize.closest(256); + for (int keySize = it->keyLength.min(); keySize <= it->keyLength.max(); + keySize += it->keyLength.inc()) { + cerr << it->name << ", key length " << keySize << ", block size " + << blockSize << ": "; - shared_ptr cipher = CipherV1::New( it->name, keySize ); - if(!cipher) - { + shared_ptr cipher = CipherV1::New(it->name, keySize); + if (!cipher) { cerr << "FAILED TO CREATE\n"; - } else - { - try - { - if(runTests( cipher, false )) + } else { + try { + if (runTests(cipher, false)) cerr << "OK\n"; else cerr << "FAILED\n"; - } catch( Error &er ) - { + } + catch (Error &er) { cerr << "Error: " << er.what() << "\n"; } } @@ -525,20 +439,17 @@ int main(int argc, char *argv[]) // run one test with verbose output too.. shared_ptr cipher = CipherV1::New("AES", 192); - if(!cipher) - { + if (!cipher) { cerr << "\nNo AES cipher found, skipping verbose test.\n"; - } else - { - cerr << "\nVerbose output for " << cipher->interface().name() - << " test, key length " << cipher->keySize()*8 << ", block size " - << FSBlockSize << ":\n"; + } else { + cerr << "\nVerbose output for " << cipher->interface().name() + << " test, key length " << cipher->keySize() * 8 << ", block size " + << FSBlockSize << ":\n"; - runTests( cipher, true ); + runTests(cipher, true); } CipherV1::shutdown(isThreaded); return 0; } - diff --git a/fs/encfs.cpp b/fs/encfs.cpp index e3e4f18..bfaaacc 100644 --- a/fs/encfs.cpp +++ b/fs/encfs.cpp @@ -3,8 +3,8 @@ * ***************************************************************************** * Copyright (c) 2003-2007, Valient Gough - * - * This program is free software; you can distribute it and/or modify it under + * + * This program is free software; you can distribute it and/or modify it under * the terms of the GNU General Public License (GPL), as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. @@ -71,16 +71,15 @@ using std::vector; namespace encfs { #ifndef MIN -#define MIN(a,b) (((a)<(b)) ? (a): (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #define ESUCCESS 0 -#define GET_FN(ctx, finfo) ctx->getNode((void*)(uintptr_t)finfo->fh) +#define GET_FN(ctx, finfo) ctx->getNode((void *)(uintptr_t)finfo->fh) -static EncFS_Context * context() -{ - return (EncFS_Context*)fuse_get_context()->private_data; +static EncFS_Context *context() { + return (EncFS_Context *)fuse_get_context()->private_data; } /* @@ -95,94 +94,82 @@ static EncFS_Context * context() */ // helper function -- apply a functor to a cipher path, given the plain path -template -static int withCipherPath( const char *opName, const char *path, - int (*op)(EncFS_Context *, const string &name, T data ), T data, - bool passReturnCode = false ) -{ +template +static int withCipherPath(const char *opName, const char *path, + int (*op)(EncFS_Context *, const string &name, + T data), + T data, bool passReturnCode = false) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { - string cyName = FSRoot->cipherPath( path ); + try { + string cyName = FSRoot->cipherPath(path); VLOG(1) << opName << " " << cyName.c_str(); - res = op( ctx, cyName, data ); + res = op(ctx, cyName, data); - if(res == -1) - { + if (res == -1) { res = -errno; LOG(INFO) << opName << " error: " << strerror(-res); - } else if(!passReturnCode) + } else if (!passReturnCode) res = ESUCCESS; - } catch( Error &err ) - { - LOG(ERROR) << "error caught in " << opName << - ":" << err.what(); + } + catch (Error &err) { + LOG(ERROR) << "error caught in " << opName << ":" << err.what(); } return res; } // helper function -- apply a functor to a node -template -static int withFileNode( const char *opName, - const char *path, struct fuse_file_info *fi, - int (*op)(FileNode *, T data ), T data ) -{ +template +static int withFileNode(const char *opName, const char *path, + struct fuse_file_info *fi, + int (*op)(FileNode *, T data), T data) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { + try { shared_ptr fnode; - if(fi != NULL) + if (fi != NULL) fnode = GET_FN(ctx, fi); else - fnode = FSRoot->lookupNode( path, opName ); + fnode = FSRoot->lookupNode(path, opName); rAssert(fnode != NULL); VLOG(1) << opName << " " << fnode->cipherName(); - res = op( fnode.get(), data ); + res = op(fnode.get(), data); LOG_IF(INFO, res < 0) << opName << " error: " << strerror(-res); - } catch( Error &err ) - { - LOG(ERROR) << "error caught in " << opName << - ":" << err.what(); + } + catch (Error &err) { + LOG(ERROR) << "error caught in " << opName << ":" << err.what(); } return res; } -int _do_getattr(FileNode *fnode, struct stat *stbuf) -{ +int _do_getattr(FileNode *fnode, struct stat *stbuf) { int res = fnode->getAttr(stbuf); - if(res == ESUCCESS && S_ISLNK(stbuf->st_mode)) - { + if (res == ESUCCESS && S_ISLNK(stbuf->st_mode)) { EncFS_Context *ctx = context(); shared_ptr FSRoot = ctx->getRoot(&res); - if(FSRoot) - { + if (FSRoot) { // determine plaintext link size.. Easiest to read and decrypt.. - vector buf(stbuf->st_size+1, 0); + vector buf(stbuf->st_size + 1, 0); - res = ::readlink( fnode->cipherName(), &buf[0], stbuf->st_size ); - if(res >= 0) - { + res = ::readlink(fnode->cipherName(), &buf[0], stbuf->st_size); + if (res >= 0) { // other functions expect c-strings to be null-terminated, which // readlink doesn't provide buf[res] = '\0'; - stbuf->st_size = FSRoot->plainPath( &buf[0] ).length(); + stbuf->st_size = FSRoot->plainPath(&buf[0]).length(); res = ESUCCESS; } else @@ -193,234 +180,199 @@ int _do_getattr(FileNode *fnode, struct stat *stbuf) return res; } -int encfs_getattr(const char *path, struct stat *stbuf) -{ - return withFileNode( "getattr", path, NULL, _do_getattr, stbuf ); +int encfs_getattr(const char *path, struct stat *stbuf) { + return withFileNode("getattr", path, NULL, _do_getattr, stbuf); } int encfs_fgetattr(const char *path, struct stat *stbuf, - struct fuse_file_info *fi) -{ - return withFileNode( "fgetattr", path, fi, _do_getattr, stbuf ); + struct fuse_file_info *fi) { + return withFileNode("fgetattr", path, fi, _do_getattr, stbuf); } -int encfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) -{ +int encfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler) { EncFS_Context *ctx = context(); int res = ESUCCESS; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { + try { - DirTraverse dt = FSRoot->openDir( path ); + DirTraverse dt = FSRoot->openDir(path); VLOG(1) << "getdir on " << FSRoot->cipherPath(path); - if(dt.valid()) - { + if (dt.valid()) { int fileType = 0; ino_t inode = 0; - std::string name = dt.nextPlaintextName( &fileType, &inode ); - while( !name.empty() ) - { - res = filler( h, name.c_str(), fileType, inode ); + std::string name = dt.nextPlaintextName(&fileType, &inode); + while (!name.empty()) { + res = filler(h, name.c_str(), fileType, inode); - if(res != ESUCCESS) - break; + if (res != ESUCCESS) break; - name = dt.nextPlaintextName( &fileType, &inode ); + name = dt.nextPlaintextName(&fileType, &inode); } - } else - { + } else { LOG(INFO) << "getdir request invalid, path: '" << path << "'"; } return res; - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "error caught in getdir: " << err.what(); return -EIO; } } -int encfs_mknod(const char *path, mode_t mode, dev_t rdev) -{ +int encfs_mknod(const char *path, mode_t mode, dev_t rdev) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { - shared_ptr fnode = FSRoot->lookupNode( path, "mknod" ); + try { + shared_ptr fnode = FSRoot->lookupNode(path, "mknod"); - VLOG(1) << "mknod on " << fnode->cipherName() - << ", mode " << mode << ", dev " << rdev; + VLOG(1) << "mknod on " << fnode->cipherName() << ", mode " << mode + << ", dev " << rdev; uid_t uid = 0; gid_t gid = 0; - if(ctx->publicFilesystem) - { + if (ctx->publicFilesystem) { fuse_context *context = fuse_get_context(); uid = context->uid; gid = context->gid; } - res = fnode->mknod( mode, rdev, uid, gid ); + res = fnode->mknod(mode, rdev, uid, gid); // Is this error due to access problems? - if(ctx->publicFilesystem && -res == EACCES) - { + if (ctx->publicFilesystem && -res == EACCES) { // try again using the parent dir's group string parent = fnode->plaintextParent(); - LOG(INFO) << "attempting public filesystem workaround for " + LOG(INFO) << "attempting public filesystem workaround for " << parent.c_str(); - shared_ptr dnode = - FSRoot->lookupNode( parent.c_str(), "mknod" ); + shared_ptr dnode = FSRoot->lookupNode(parent.c_str(), "mknod"); struct stat st; - if(dnode->getAttr( &st ) == 0) - res = fnode->mknod( mode, rdev, uid, st.st_gid ); + if (dnode->getAttr(&st) == 0) + res = fnode->mknod(mode, rdev, uid, st.st_gid); } - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "error caught in mknod: " << err.what(); } return res; } -int encfs_mkdir(const char *path, mode_t mode) -{ +int encfs_mkdir(const char *path, mode_t mode) { fuse_context *fctx = fuse_get_context(); EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { + try { uid_t uid = 0; gid_t gid = 0; - if(ctx->publicFilesystem) - { + if (ctx->publicFilesystem) { uid = fctx->uid; gid = fctx->gid; } - res = FSRoot->mkdir( path, mode, uid, gid ); + res = FSRoot->mkdir(path, mode, uid, gid); // Is this error due to access problems? - if(ctx->publicFilesystem && -res == EACCES) - { + if (ctx->publicFilesystem && -res == EACCES) { // try again using the parent dir's group - string parent = parentDirectory( path ); - shared_ptr dnode = - FSRoot->lookupNode( parent.c_str(), "mkdir" ); + string parent = parentDirectory(path); + shared_ptr dnode = FSRoot->lookupNode(parent.c_str(), "mkdir"); struct stat st; - if(dnode->getAttr( &st ) == 0) - res = FSRoot->mkdir( path, mode, uid, st.st_gid ); + if (dnode->getAttr(&st) == 0) + res = FSRoot->mkdir(path, mode, uid, st.st_gid); } - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "error caught in mkdir: " << err.what(); } return res; } -int encfs_unlink(const char *path) -{ +int encfs_unlink(const char *path) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { + try { // let DirNode handle it atomically so that it can handle race // conditions - res = FSRoot->unlink( path ); - } catch( Error &err ) - { + res = FSRoot->unlink(path); + } + catch (Error &err) { LOG(ERROR) << "error caught in unlink: " << err.what(); } return res; } -int _do_rmdir(EncFS_Context *, const string &cipherPath, int ) -{ - return rmdir( cipherPath.c_str() ); +int _do_rmdir(EncFS_Context *, const string &cipherPath, int) { + return rmdir(cipherPath.c_str()); } -int encfs_rmdir(const char *path) -{ - return withCipherPath( "rmdir", path, _do_rmdir, 0 ); +int encfs_rmdir(const char *path) { + return withCipherPath("rmdir", path, _do_rmdir, 0); } int _do_readlink(EncFS_Context *ctx, const string &cyName, - tuple data ) -{ + tuple data) { char *buf = get<0>(data); size_t size = get<1>(data); int res = ESUCCESS; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - res = ::readlink( cyName.c_str(), buf, size-1 ); + res = ::readlink(cyName.c_str(), buf, size - 1); - if(res == -1) - return -errno; + if (res == -1) return -errno; - buf[res] = '\0'; // ensure null termination + buf[res] = '\0'; // ensure null termination string decodedName; - try - { - decodedName = FSRoot->plainPath( buf ); - } catch(...) { } + try { + decodedName = FSRoot->plainPath(buf); + } + catch (...) { + } - if(!decodedName.empty()) - { - strncpy(buf, decodedName.c_str(), size-1); - buf[size-1] = '\0'; + if (!decodedName.empty()) { + strncpy(buf, decodedName.c_str(), size - 1); + buf[size - 1] = '\0'; return ESUCCESS; - } else - { + } else { LOG(WARNING) << "Error decoding link"; return -1; } } -int encfs_readlink(const char *path, char *buf, size_t size) -{ - return withCipherPath( "readlink", path, _do_readlink, - make_tuple(buf, size) ); +int encfs_readlink(const char *path, char *buf, size_t size) { + return withCipherPath("readlink", path, _do_readlink, make_tuple(buf, size)); } -int encfs_symlink(const char *from, const char *to) -{ +int encfs_symlink(const char *from, const char *to) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { + try { // allow fully qualified names in symbolic links. - string fromCName = FSRoot->relativeCipherPath( from ); - string toCName = FSRoot->cipherPath( to ); + string fromCName = FSRoot->relativeCipherPath(from); + string toCName = FSRoot->cipherPath(to); VLOG(1) << "symlink " << fromCName << " -> " << toCName; @@ -428,191 +380,159 @@ int encfs_symlink(const char *from, const char *to) // uid/gid provided by the fuse_context. int olduid = -1; int oldgid = -1; - if(ctx->publicFilesystem) - { + if (ctx->publicFilesystem) { fuse_context *context = fuse_get_context(); - olduid = setfsuid( context->uid ); - oldgid = setfsgid( context->gid ); + olduid = setfsuid(context->uid); + oldgid = setfsgid(context->gid); } - res = ::symlink( fromCName.c_str(), toCName.c_str() ); - if(olduid >= 0) - setfsuid( olduid ); - if(oldgid >= 0) - setfsgid( oldgid ); + res = ::symlink(fromCName.c_str(), toCName.c_str()); + if (olduid >= 0) setfsuid(olduid); + if (oldgid >= 0) setfsgid(oldgid); - if(res == -1) + if (res == -1) res = -errno; else res = ESUCCESS; - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "error caught in symlink: " << err.what(); } return res; } -int encfs_link(const char *from, const char *to) -{ +int encfs_link(const char *from, const char *to) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { - res = FSRoot->link( from, to ); - } catch( Error &err ) - { + try { + res = FSRoot->link(from, to); + } + catch (Error &err) { LOG(ERROR) << "error caught in link: " << err.what(); } return res; } -int encfs_rename(const char *from, const char *to) -{ +int encfs_rename(const char *from, const char *to) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { - res = FSRoot->rename( from, to ); - } catch( Error &err ) - { + try { + res = FSRoot->rename(from, to); + } + catch (Error &err) { LOG(ERROR) << "error caught in rename: " << err.what(); } return res; } -int _do_chmod(EncFS_Context *, const string &cipherPath, mode_t mode) -{ +int _do_chmod(EncFS_Context *, const string &cipherPath, mode_t mode) { #ifdef HAVE_LCHMOD - return lchmod( cipherPath.c_str(), mode ); + return lchmod(cipherPath.c_str(), mode); #else - return chmod( cipherPath.c_str(), mode ); + return chmod(cipherPath.c_str(), mode); #endif } -int encfs_chmod(const char *path, mode_t mode) -{ - return withCipherPath( "chmod", path, _do_chmod, mode ); +int encfs_chmod(const char *path, mode_t mode) { + return withCipherPath("chmod", path, _do_chmod, mode); } -int _do_chown(EncFS_Context *, const string &cyName, - tuple data) -{ - int res = lchown( cyName.c_str(), get<0>(data), get<1>(data) ); +int _do_chown(EncFS_Context *, const string &cyName, tuple data) { + int res = lchown(cyName.c_str(), get<0>(data), get<1>(data)); return (res == -1) ? -errno : ESUCCESS; } -int encfs_chown(const char *path, uid_t uid, gid_t gid) -{ - return withCipherPath( "chown", path, _do_chown, make_tuple(uid, gid)); +int encfs_chown(const char *path, uid_t uid, gid_t gid) { + return withCipherPath("chown", path, _do_chown, make_tuple(uid, gid)); } -int _do_truncate( FileNode *fnode, off_t size ) -{ - return fnode->truncate( size ); +int _do_truncate(FileNode *fnode, off_t size) { return fnode->truncate(size); } + +int encfs_truncate(const char *path, off_t size) { + return withFileNode("truncate", path, NULL, _do_truncate, size); } -int encfs_truncate(const char *path, off_t size) -{ - return withFileNode( "truncate", path, NULL, _do_truncate, size ); +int encfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) { + return withFileNode("ftruncate", path, fi, _do_truncate, size); } -int encfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) -{ - return withFileNode( "ftruncate", path, fi, _do_truncate, size ); -} - -int _do_utime(EncFS_Context *, const string &cyName, struct utimbuf *buf) -{ - int res = utime( cyName.c_str(), buf); +int _do_utime(EncFS_Context *, const string &cyName, struct utimbuf *buf) { + int res = utime(cyName.c_str(), buf); return (res == -1) ? -errno : ESUCCESS; } -int encfs_utime(const char *path, struct utimbuf *buf) -{ - return withCipherPath( "utime", path, _do_utime, buf ); +int encfs_utime(const char *path, struct utimbuf *buf) { + return withCipherPath("utime", path, _do_utime, buf); } -int _do_utimens(EncFS_Context *, const string &cyName, - const struct timespec ts[2]) -{ +int _do_utimens(EncFS_Context *, const string &cyName, + const struct timespec ts[2]) { struct timeval tv[2]; tv[0].tv_sec = ts[0].tv_sec; tv[0].tv_usec = ts[0].tv_nsec / 1000; tv[1].tv_sec = ts[1].tv_sec; tv[1].tv_usec = ts[1].tv_nsec / 1000; - int res = lutimes( cyName.c_str(), tv); + int res = lutimes(cyName.c_str(), tv); return (res == -1) ? -errno : ESUCCESS; } -int encfs_utimens(const char *path, const struct timespec ts[2] ) -{ - return withCipherPath( "utimens", path, _do_utimens, ts ); +int encfs_utimens(const char *path, const struct timespec ts[2]) { + return withCipherPath("utimens", path, _do_utimens, ts); } -int encfs_open(const char *path, struct fuse_file_info *file) -{ +int encfs_open(const char *path, struct fuse_file_info *file) { EncFS_Context *ctx = context(); int res = -EIO; shared_ptr FSRoot = ctx->getRoot(&res); - if(!FSRoot) - return res; + if (!FSRoot) return res; - try - { - shared_ptr fnode = - FSRoot->openNode( path, "open", file->flags, &res ); + try { + shared_ptr fnode = + FSRoot->openNode(path, "open", file->flags, &res); - if(fnode) - { - VLOG(1) << "encfs_open for " << fnode->cipherName() - << ", flags " << file->flags; + if (fnode) { + VLOG(1) << "encfs_open for " << fnode->cipherName() << ", flags " + << file->flags; - if( res >= 0 ) - { + if (res >= 0) { file->fh = (uintptr_t)ctx->putNode(path, fnode); res = ESUCCESS; } } - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "error caught in open: " << err.what(); } return res; } -int _do_flush(FileNode *fnode, int ) -{ +int _do_flush(FileNode *fnode, int) { /* Flush can be called multiple times for an open file, so it doesn't close the file. However it is important to call close() for some underlying filesystems (like NFS). */ - int res = fnode->open( O_RDONLY ); - if(res >= 0) - { + int res = fnode->open(O_RDONLY); + if (res >= 0) { int fh = res; res = close(dup(fh)); - if(res == -1) - res = -errno; + if (res == -1) res = -errno; } return res; } -int encfs_flush(const char *path, struct fuse_file_info *fi) -{ - return withFileNode( "flush", path, fi, _do_flush, 0 ); +int encfs_flush(const char *path, struct fuse_file_info *fi) { + return withFileNode("flush", path, fi, _do_flush, 0); } /* @@ -620,83 +540,70 @@ Note: This is advisory -- it might benefit us to keep file nodes around for a bit after they are released just in case they are reopened soon. But that requires a cache layer. */ -int encfs_release(const char *path, struct fuse_file_info *finfo) -{ +int encfs_release(const char *path, struct fuse_file_info *finfo) { EncFS_Context *ctx = context(); - try - { - ctx->eraseNode( path, (void*)(uintptr_t)finfo->fh ); + try { + ctx->eraseNode(path, (void *)(uintptr_t)finfo->fh); return ESUCCESS; - } catch( Error &err ) - { + } + catch (Error &err) { LOG(ERROR) << "error caught in release: " << err.what(); return -EIO; } } -int _do_read(FileNode *fnode, tuple data) -{ - return fnode->read( get<2>(data), get<0>(data), get<1>(data)); +int _do_read(FileNode *fnode, tuple data) { + return fnode->read(get<2>(data), get<0>(data), get<1>(data)); } int encfs_read(const char *path, char *buf, size_t size, off_t offset, - struct fuse_file_info *file) -{ - return withFileNode( "read", path, file, _do_read, - make_tuple((unsigned char *)buf, size, offset)); + struct fuse_file_info *file) { + return withFileNode("read", path, file, _do_read, + make_tuple((unsigned char *)buf, size, offset)); } -int _do_fsync(FileNode *fnode, int dataSync) -{ - return fnode->sync( dataSync != 0 ); +int _do_fsync(FileNode *fnode, int dataSync) { + return fnode->sync(dataSync != 0); } -int encfs_fsync(const char *path, int dataSync, - struct fuse_file_info *file) -{ - return withFileNode( "fsync", path, file, _do_fsync, dataSync ); +int encfs_fsync(const char *path, int dataSync, struct fuse_file_info *file) { + return withFileNode("fsync", path, file, _do_fsync, dataSync); } -int _do_write(FileNode *fnode, tuple data) -{ +int _do_write(FileNode *fnode, tuple data) { size_t size = get<1>(data); - if(fnode->write( get<2>(data), (unsigned char *)get<0>(data), size )) + if (fnode->write(get<2>(data), (unsigned char *)get<0>(data), size)) return size; else return -EIO; } -int encfs_write(const char *path, const char *buf, size_t size, - off_t offset, struct fuse_file_info *file) -{ +int encfs_write(const char *path, const char *buf, size_t size, off_t offset, + struct fuse_file_info *file) { return withFileNode("write", path, file, _do_write, - make_tuple(buf, size, offset)); + make_tuple(buf, size, offset)); } // statfs works even if encfs is detached.. -int encfs_statfs(const char *path, struct statvfs *st) -{ +int encfs_statfs(const char *path, struct statvfs *st) { EncFS_Context *ctx = context(); int res = -EIO; - try - { - (void)path; // path should always be '/' for now.. - rAssert( st != NULL ); + try { + (void)path; // path should always be '/' for now.. + rAssert(st != NULL); string cyName = ctx->rootCipherDir; VLOG(1) << "doing statfs of " << cyName; - res = statvfs( cyName.c_str(), st ); - if(!res) - { + res = statvfs(cyName.c_str(), st); + if (!res) { // adjust maximum name length.. - st->f_namemax = 6 * (st->f_namemax - 2) / 8; // approx.. + st->f_namemax = 6 * (st->f_namemax - 2) / 8; // approx.. } - if(res == -1) - res = -errno; - } catch( Error &err ) - { + if (res == -1) res = -errno; + } + catch (Error &err) { LOG(ERROR) << "error caught in statfs: " << err.what(); } return res; @@ -706,102 +613,87 @@ int encfs_statfs(const char *path, struct statvfs *st) #ifdef XATTR_ADD_OPT -int _do_setxattr(EncFS_Context *, const string &cyName, - tuple data) -{ +int _do_setxattr(EncFS_Context *, const string &cyName, + tuple data) { int options = XATTR_NOFOLLOW; - return ::setxattr( cyName.c_str(), get<0>(data), get<1>(data), - get<2>(data), get<3>(data), options ); + return ::setxattr(cyName.c_str(), get<0>(data), get<1>(data), get<2>(data), + get<3>(data), options); } -int encfs_setxattr( const char *path, const char *name, - const char *value, size_t size, int flags, uint32_t position ) -{ +int encfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags, uint32_t position) { (void)flags; - return withCipherPath( "setxattr", path, _do_setxattr, - make_tuple(name, value, size, position) ); + return withCipherPath("setxattr", path, _do_setxattr, + make_tuple(name, value, size, position)); } #else -int _do_setxattr(EncFS_Context *, const string &cyName, - tuple data) -{ - return ::setxattr( cyName.c_str(), get<0>(data), get<1>(data), - get<2>(data), get<3>(data) ); +int _do_setxattr(EncFS_Context *, const string &cyName, + tuple data) { + return ::setxattr(cyName.c_str(), get<0>(data), get<1>(data), get<2>(data), + get<3>(data)); } -int encfs_setxattr( const char *path, const char *name, - const char *value, size_t size, int flags ) -{ - return withCipherPath( "setxattr", path, _do_setxattr, - make_tuple(name, value, size, flags) ); +int encfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags) { + return withCipherPath("setxattr", path, _do_setxattr, + make_tuple(name, value, size, flags)); } #endif #ifdef XATTR_ADD_OPT int _do_getxattr(EncFS_Context *, const string &cyName, - tuple data) -{ + tuple data) { int options = 0; - return ::getxattr( cyName.c_str(), get<0>(data), - get<1>(data), get<2>(data), get<3>(data), options ); + return ::getxattr(cyName.c_str(), get<0>(data), get<1>(data), get<2>(data), + get<3>(data), options); } -int encfs_getxattr( const char *path, const char *name, - char *value, size_t size, uint32_t position ) -{ - return withCipherPath( "getxattr", path, _do_getxattr, - make_tuple(name, (void *)value, size, position), true ); +int encfs_getxattr(const char *path, const char *name, char *value, size_t size, + uint32_t position) { + return withCipherPath("getxattr", path, _do_getxattr, + make_tuple(name, (void *)value, size, position), true); } #else int _do_getxattr(EncFS_Context *, const string &cyName, - tuple data) -{ - return ::getxattr( cyName.c_str(), get<0>(data), - get<1>(data), get<2>(data)); + tuple data) { + return ::getxattr(cyName.c_str(), get<0>(data), get<1>(data), get<2>(data)); } -int encfs_getxattr( const char *path, const char *name, - char *value, size_t size ) -{ - return withCipherPath( "getxattr", path, _do_getxattr, - make_tuple(name, (void *)value, size), true ); +int encfs_getxattr(const char *path, const char *name, char *value, + size_t size) { + return withCipherPath("getxattr", path, _do_getxattr, + make_tuple(name, (void *)value, size), true); } #endif int _do_listxattr(EncFS_Context *, const string &cyName, - tuple data) -{ + tuple data) { #ifdef XATTR_ADD_OPT int options = 0; - int res = ::listxattr( cyName.c_str(), get<0>(data), get<1>(data), - options ); + int res = ::listxattr(cyName.c_str(), get<0>(data), get<1>(data), options); #else - int res = ::listxattr( cyName.c_str(), get<0>(data), get<1>(data) ); + int res = ::listxattr(cyName.c_str(), get<0>(data), get<1>(data)); #endif return (res == -1) ? -errno : res; } -int encfs_listxattr( const char *path, char *list, size_t size ) -{ - return withCipherPath( "listxattr", path, _do_listxattr, - make_tuple(list, size), true ); +int encfs_listxattr(const char *path, char *list, size_t size) { + return withCipherPath("listxattr", path, _do_listxattr, + make_tuple(list, size), true); } -int _do_removexattr(EncFS_Context *, const string &cyName, const char *name) -{ +int _do_removexattr(EncFS_Context *, const string &cyName, const char *name) { #ifdef XATTR_ADD_OPT int options = 0; - int res = ::removexattr( cyName.c_str(), name, options ); + int res = ::removexattr(cyName.c_str(), name, options); #else - int res = ::removexattr( cyName.c_str(), name ); + int res = ::removexattr(cyName.c_str(), name); #endif return (res == -1) ? -errno : res; } -int encfs_removexattr( const char *path, const char *name ) -{ - return withCipherPath( "removexattr", path, _do_removexattr, name ); +int encfs_removexattr(const char *path, const char *name) { + return withCipherPath("removexattr", path, _do_removexattr, name); } } // namespace encfs -#endif // HAVE_XATTR - +#endif // HAVE_XATTR diff --git a/fs/encfs.h b/fs/encfs.h index d380185..bd3d183 100644 --- a/fs/encfs.h +++ b/fs/encfs.h @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. + * 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 @@ -32,36 +32,32 @@ #ifndef linux #include -static __inline int setfsuid(uid_t uid) -{ - uid_t olduid = geteuid(); +static __inline int setfsuid(uid_t uid) { + uid_t olduid = geteuid(); - seteuid(uid); + seteuid(uid); - if (errno != EINVAL) - errno = 0; + if (errno != EINVAL) errno = 0; - return olduid; + return olduid; } -static __inline int setfsgid(gid_t gid) -{ - gid_t oldgid = getegid(); +static __inline int setfsgid(gid_t gid) { + gid_t oldgid = getegid(); - setegid(gid); + setegid(gid); - if (errno != EINVAL) - errno = 0; + if (errno != EINVAL) errno = 0; - return oldgid; + return oldgid; } #endif namespace encfs { int encfs_getattr(const char *path, struct stat *stbuf); -int encfs_fgetattr(const char *path, struct stat *stbuf, - struct fuse_file_info *fi); +int encfs_fgetattr(const char *path, struct stat *stbuf, + struct fuse_file_info *fi); int encfs_readlink(const char *path, char *buf, size_t size); int encfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler); int encfs_mknod(const char *path, mode_t mode, dev_t rdev); @@ -74,40 +70,38 @@ int encfs_link(const char *from, const char *to); int encfs_chmod(const char *path, mode_t mode); int encfs_chown(const char *path, uid_t uid, gid_t gid); int encfs_truncate(const char *path, off_t size); -int encfs_ftruncate(const char *path, off_t size, - struct fuse_file_info *fi); +int encfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi); int encfs_utime(const char *path, struct utimbuf *buf); int encfs_open(const char *path, struct fuse_file_info *info); int encfs_release(const char *path, struct fuse_file_info *info); int encfs_read(const char *path, char *buf, size_t size, off_t offset, - struct fuse_file_info *info); + struct fuse_file_info *info); int encfs_write(const char *path, const char *buf, size_t size, off_t offset, - struct fuse_file_info *info); + struct fuse_file_info *info); int encfs_statfs(const char *, struct statvfs *fst); int encfs_flush(const char *, struct fuse_file_info *info); int encfs_fsync(const char *path, int flags, struct fuse_file_info *info); #ifdef HAVE_XATTR -# ifdef XATTR_ADD_OPT -int encfs_setxattr( const char *path, const char *name, const char *value, - size_t size, int flags, uint32_t position); -int encfs_getxattr( const char *path, const char *name, char *value, - size_t size, uint32_t position ); -# else -int encfs_setxattr( const char *path, const char *name, const char *value, - size_t size, int flags); -int encfs_getxattr( const char *path, const char *name, char *value, - size_t size ); -# endif - -int encfs_listxattr( const char *path, char *list, size_t size ); -int encfs_removexattr( const char *path, const char *name ); +#ifdef XATTR_ADD_OPT +int encfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags, uint32_t position); +int encfs_getxattr(const char *path, const char *name, char *value, size_t size, + uint32_t position); +#else +int encfs_setxattr(const char *path, const char *name, const char *value, + size_t size, int flags); +int encfs_getxattr(const char *path, const char *name, char *value, + size_t size); #endif -int encfs_utimens( const char *path, const struct timespec ts[2] ); +int encfs_listxattr(const char *path, char *list, size_t size); +int encfs_removexattr(const char *path, const char *name); +#endif + +int encfs_utimens(const char *path, const struct timespec ts[2]); } // namespace encfs #endif - diff --git a/fs/test_BlockIO.cpp b/fs/test_BlockIO.cpp index 6b43be7..d79c32f 100644 --- a/fs/test_BlockIO.cpp +++ b/fs/test_BlockIO.cpp @@ -7,7 +7,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -39,7 +39,7 @@ TEST(BlockFileIOTest, BasicIO) { MemFileIO base(1024); ASSERT_EQ(1024, base.getSize()); - FSConfigPtr cfg = makeConfig( CipherV1::New("Null"), 512); + FSConfigPtr cfg = makeConfig(CipherV1::New("Null"), 512); MemBlockFileIO block(512, cfg); block.truncate(1024); ASSERT_EQ(1024, block.getSize()); @@ -56,7 +56,7 @@ TEST(BlockFileIOTest, BasicIO) { req.offset = i * 256; memset(req.data, 0, req.dataLen); ASSERT_TRUE(base.write(req)); - + req.offset = i * 256; memset(req.data, 0, req.dataLen); ASSERT_TRUE(block.write(req)); @@ -66,4 +66,3 @@ TEST(BlockFileIOTest, BasicIO) { } } // namespace encfs - diff --git a/fs/test_IO.cpp b/fs/test_IO.cpp index 9e4bfd6..63852ed 100644 --- a/fs/test_IO.cpp +++ b/fs/test_IO.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -68,13 +68,9 @@ void testMacIO(FSConfigPtr& cfg) { comparisonTest(cfg, test.get(), dup.get()); } -TEST(IOTest, NullMacIO) { - runWithCipher("Null", 512, testMacIO); -} +TEST(IOTest, NullMacIO) { runWithCipher("Null", 512, testMacIO); } -TEST(IOTest, MacIO) { - runWithAllCiphers(testMacIO); -} +TEST(IOTest, MacIO) { runWithAllCiphers(testMacIO); } void testBasicCipherIO(FSConfigPtr& cfg) { shared_ptr base(new MemFileIO(0)); @@ -97,16 +93,13 @@ void testBasicCipherIO(FSConfigPtr& cfg) { for (unsigned int i = 0; i < sizeof(buf); ++i) { bool match = (buf[i] == req.data[i]); ASSERT_TRUE(match) << "mismatched data at offset " << i; - if (!match) - break; + if (!match) break; } delete[] req.data; } -TEST(IOTest, BasicCipherFileIO) { - runWithAllCiphers(testBasicCipherIO); -} +TEST(IOTest, BasicCipherFileIO) { runWithAllCiphers(testBasicCipherIO); } void testCipherIO(FSConfigPtr& cfg) { shared_ptr base(new MemFileIO(0)); @@ -116,13 +109,8 @@ void testCipherIO(FSConfigPtr& cfg) { comparisonTest(cfg, test.get(), dup.get()); } -TEST(IOTest, NullCipherFileIO) { - runWithCipher("Null", 512, testCipherIO); -} +TEST(IOTest, NullCipherFileIO) { runWithCipher("Null", 512, testCipherIO); } -TEST(IOTest, CipherFileIO) { - runWithAllCiphers(testCipherIO); -} +TEST(IOTest, CipherFileIO) { runWithAllCiphers(testCipherIO); } } // namespace - diff --git a/fs/testing.cpp b/fs/testing.cpp index 960843b..a5a0aef 100644 --- a/fs/testing.cpp +++ b/fs/testing.cpp @@ -8,7 +8,7 @@ * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any - * later version. + * 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 @@ -19,7 +19,6 @@ * along with this program. If not, see . */ - #include "fs/testing.h" #include @@ -68,8 +67,9 @@ void runWithAllCiphers(void (*func)(FSConfigPtr& config)) { for (it = algorithms.begin(); it != algorithms.end(); ++it) { int blockSize = it->blockSize.closest(512); int keyLength = it->keyLength.closest(128); - SCOPED_TRACE(testing::Message() << "Testng with cipher " << it->name - << ", blocksize " << blockSize << ", keyLength " << keyLength); + SCOPED_TRACE(testing::Message() << "Testng with cipher " << it->name + << ", blocksize " << blockSize + << ", keyLength " << keyLength); shared_ptr cipher = CipherV1::New(it->iface, keyLength); ASSERT_TRUE(cipher.get() != NULL); @@ -80,7 +80,7 @@ void runWithAllCiphers(void (*func)(FSConfigPtr& config)) { void truncate(FileIO* a, FileIO* b, int len) { SCOPED_TRACE(testing::Message() << "Truncate from " << a->getSize() - << " to len " << len); + << " to len " << len); a->truncate(len); ASSERT_EQ(len, a->getSize()); @@ -100,8 +100,8 @@ void writeRandom(FSConfigPtr& cfg, FileIO* a, FileIO* b, int offset, int len) { if (b->getSize() < offset + len) { b->truncate(offset + len); } - - unsigned char *buf = new unsigned char[len]; + + unsigned char* buf = new unsigned char[len]; ASSERT_TRUE(cfg->cipher->pseudoRandomize(buf, len)); IORequest req; @@ -117,7 +117,7 @@ void writeRandom(FSConfigPtr& cfg, FileIO* a, FileIO* b, int offset, int len) { req.dataLen = len; ASSERT_EQ(len, a->read(req)); ASSERT_TRUE(memcmp(req.data, buf, len) == 0); - + memcpy(req.data, buf, len); req.offset = offset; req.dataLen = len; @@ -137,9 +137,9 @@ void writeRandom(FSConfigPtr& cfg, FileIO* a, FileIO* b, int offset, int len) { void compare(FileIO* a, FileIO* b, int offset, int len) { SCOPED_TRACE(testing::Message() << "compare " << offset << ", " << len - << " from file length " << a->getSize()); - unsigned char *buf1 = new unsigned char[len]; - unsigned char *buf2 = new unsigned char[len]; + << " from file length " << a->getSize()); + unsigned char* buf1 = new unsigned char[len]; + unsigned char* buf2 = new unsigned char[len]; memset(buf1, 0, len); memset(buf2, 0, len); @@ -155,12 +155,12 @@ void compare(FileIO* a, FileIO* b, int offset, int len) { ssize_t size2 = b->read(req); ASSERT_EQ(size1, size2); - for(int i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { bool match = (buf1[i] == buf2[i]); ASSERT_TRUE(match) << "mismatched data at offset " << i << " of " << len - << ", got " << int(buf1[i]) << " and " << int(buf2[i]); - if(!match) { - break; + << ", got " << int(buf1[i]) << " and " << int(buf2[i]); + if (!match) { + break; } } @@ -169,15 +169,14 @@ void compare(FileIO* a, FileIO* b, int offset, int len) { } void comparisonTest(FSConfigPtr& cfg, FileIO* a, FileIO* b) { - const int size = 2*1024; + const int size = 2 * 1024; writeRandom(cfg, a, b, 0, size); if (testing::Test::HasFatalFailure()) return; for (int i = 0; i < 10000; i++) { SCOPED_TRACE(testing::Message() << "Test Loop " << i); int len = 128 + random() % 512; - int offset = (len == a->getSize()) ? 0 - : random() % (a->getSize() - len); + int offset = (len == a->getSize()) ? 0 : random() % (a->getSize() - len); writeRandom(cfg, a, b, offset, len); if (testing::Test::HasFatalFailure()) return; ASSERT_EQ(a->getSize(), b->getSize()); @@ -187,10 +186,9 @@ void comparisonTest(FSConfigPtr& cfg, FileIO* a, FileIO* b) { compare(a, b, 0, a->getSize()); } -int main(int argc, char **argv) { +int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } } // namespace encfs - diff --git a/fs/testing.h b/fs/testing.h index 04ec7c3..39f4ce4 100644 --- a/fs/testing.h +++ b/fs/testing.h @@ -24,4 +24,3 @@ void compare(FileIO* a, FileIO* b, int offset, int len); } // namespace encfs #endif - diff --git a/util/encfsctl.cpp b/util/encfsctl.cpp index 7e0d49f..92f6ff3 100644 --- a/util/encfsctl.cpp +++ b/util/encfsctl.cpp @@ -3,8 +3,8 @@ * ***************************************************************************** * Copyright (c) 2004, Valient Gough - * - * This program is free software; you can distribute it and/or modify it under + * + * This program is free software; you can distribute it and/or modify it under * the terms of the GNU General Public License (GPL), as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. @@ -15,7 +15,6 @@ * more details. */ - #include "fs/encfs.h" #include "base/autosprintf.h" @@ -54,112 +53,121 @@ using std::endl; using std::string; using std::vector; -static int showInfo( int argc, char **argv ); -static int showVersion( int argc, char **argv ); -static int showCiphers( int argc, char **argv ); -static int chpasswd( int argc, char **argv ); -static int chpasswdAutomaticly( int argc, char **argv ); -static int cmd_ls( int argc, char **argv ); -static int cmd_decode( int argc, char **argv ); -static int cmd_encode( int argc, char **argv ); -static int cmd_showcruft( int argc, char **argv ); -static int cmd_cat( int argc, char **argv ); -static int cmd_export( int argc, char **argv ); -static int cmd_showKey( int argc, char **argv ); +static int showInfo(int argc, char **argv); +static int showVersion(int argc, char **argv); +static int showCiphers(int argc, char **argv); +static int chpasswd(int argc, char **argv); +static int chpasswdAutomaticly(int argc, char **argv); +static int cmd_ls(int argc, char **argv); +static int cmd_decode(int argc, char **argv); +static int cmd_encode(int argc, char **argv); +static int cmd_showcruft(int argc, char **argv); +static int cmd_cat(int argc, char **argv); +static int cmd_export(int argc, char **argv); +static int cmd_showKey(int argc, char **argv); -struct CommandOpts -{ +struct CommandOpts { const char *name; int minOptions; int maxOptions; int (*func)(int argc, char **argv); const char *argStr; const char *usageStr; -} commands[] = -{ - {"info", 1, 1, showInfo, "(root dir)", - // xgroup(usage) - gettext_noop(" -- show information (Default command)")}, - {"showKey", 1, 1, cmd_showKey, "(root dir)", - // xgroup(usage) - gettext_noop(" -- show key")}, - {"passwd", 1, 1, chpasswd, "(root dir)", - // xgroup(usage) - gettext_noop(" -- change password for volume")}, - {"autopasswd", 1, 1, chpasswdAutomaticly, "(root dir)", - // xgroup(usage) - gettext_noop(" -- change password for volume, taking password" - " from standard input.\n\tNo prompts are issued.")}, - {"ls", 1, 2, cmd_ls, 0,0}, - {"showcruft", 1, 1, cmd_showcruft, "(root dir)", - // xgroup(usage) - gettext_noop(" -- show undecodable filenames in the volume")}, - {"cat", 2, 2, cmd_cat, "(root dir) path", - // xgroup(usage) - gettext_noop(" -- decodes the file and cats it to standard out")}, - {"decode", 1, 100, cmd_decode, "[--extpass=prog] (root dir) [encoded-name ...]", - // xgroup(usage) - gettext_noop(" -- decodes name and prints plaintext version")}, - {"encode", 1, 100, cmd_encode, "[--extpass=prog] (root dir) [plaintext-name ...]", - // xgroup(usage) - gettext_noop(" -- encodes a filename and print result")}, - {"export", 2, 2, cmd_export, "(root dir) path", - // xgroup(usage) - gettext_noop(" -- decrypts a volume and writes results to path")}, - {"ciphers", 0, 0, showCiphers, "", - // xgroup(usage) - gettext_noop(" -- show available ciphers")}, - {"version", 0, 0, showVersion, "", - // xgroup(usage) - gettext_noop(" -- print version number and exit")}, - {0,0,0,0,0,0} -}; +} commands[] = { + {"info", 1, 1, + showInfo, "(root dir)", + // xgroup(usage) + gettext_noop(" -- show information (Default command)")}, + {"showKey", 1, 1, cmd_showKey, "(root dir)", + // xgroup(usage) + gettext_noop(" -- show key")}, + {"passwd", 1, 1, + chpasswd, "(root dir)", + // xgroup(usage) + gettext_noop(" -- change password for volume")}, + {"autopasswd", 1, 1, chpasswdAutomaticly, "(root dir)", + // xgroup(usage) + gettext_noop( + " -- change password for volume, taking password" + " from standard input.\n\tNo prompts are issued.")}, + {"ls", 1, 2, cmd_ls, 0, 0}, + {"showcruft", + 1, + 1, + cmd_showcruft, + "(root dir)", + // xgroup(usage) + gettext_noop(" -- show undecodable filenames in the volume")}, + {"cat", + 2, + 2, + cmd_cat, + "(root dir) path", + // xgroup(usage) + gettext_noop(" -- decodes the file and cats it to standard out")}, + {"decode", + 1, + 100, + cmd_decode, + "[--extpass=prog] (root dir) [encoded-name ...]", + // xgroup(usage) + gettext_noop(" -- decodes name and prints plaintext version")}, + {"encode", 1, + 100, cmd_encode, + "[--extpass=prog] (root dir) [plaintext-name ...]", + // xgroup(usage) + gettext_noop(" -- encodes a filename and print result")}, + {"export", + 2, + 2, + cmd_export, + "(root dir) path", + // xgroup(usage) + gettext_noop(" -- decrypts a volume and writes results to path")}, + {"ciphers", 0, 0, showCiphers, "", + // xgroup(usage) + gettext_noop(" -- show available ciphers")}, + {"version", 0, 0, showVersion, "", + // xgroup(usage) + gettext_noop(" -- print version number and exit")}, + {0, 0, 0, 0, 0, 0}}; - -static -void usage(const char *name) -{ +static void usage(const char *name) { cerr << autosprintf(_("encfsctl version %s"), VERSION) << "\n" - << _("Usage:\n") - // displays usage commands, eg "./encfs (root dir) ..." - // xgroup(usage) - << autosprintf(_("%s (root dir)\n" - " -- displays information about the filesystem, or \n"), name); + << _("Usage:\n") + // displays usage commands, eg "./encfs (root dir) ..." + // xgroup(usage) + << autosprintf( + _("%s (root dir)\n" + " -- displays information about the filesystem, or \n"), + name); int offset = 0; - while(commands[offset].name != 0) - { - if( commands[offset].argStr != 0 ) - { - cerr << "encfsctl " << commands[offset].name << " " - << commands[offset].argStr << "\n" - << gettext( commands[offset].usageStr ) << "\n"; + while (commands[offset].name != 0) { + if (commands[offset].argStr != 0) { + cerr << "encfsctl " << commands[offset].name << " " + << commands[offset].argStr << "\n" + << gettext(commands[offset].usageStr) << "\n"; } ++offset; } cerr << "\n" - // xgroup(usage) - << autosprintf(_("Example: \n%s info ~/.crypt\n"), name) - << "\n"; + // xgroup(usage) + << autosprintf(_("Example: \n%s info ~/.crypt\n"), name) << "\n"; } -static bool checkDir( string &rootDir ) -{ - if( !isDirectory( rootDir.c_str() )) - { - cout << autosprintf(_("directory %s does not exist.\n"), - rootDir.c_str()); +static bool checkDir(string &rootDir) { + if (!isDirectory(rootDir.c_str())) { + cout << autosprintf(_("directory %s does not exist.\n"), rootDir.c_str()); return false; } - if(rootDir[ rootDir.length()-1 ] != '/') - rootDir.append("/"); + if (rootDir[rootDir.length() - 1] != '/') rootDir.append("/"); return true; } -static int showVersion( int argc, char **argv ) -{ +static int showVersion(int argc, char **argv) { (void)argc; (void)argv; // xgroup(usage) @@ -168,46 +176,45 @@ static int showVersion( int argc, char **argv ) return EXIT_SUCCESS; } -static int showCiphers( int argc, char **argv ) -{ +static int showCiphers(int argc, char **argv) { (void)argc; (void)argv; cout << _("Block modes:\n"); - for (const string& name : BlockCipher::GetRegistry().GetAll()) { + for (const string &name : BlockCipher::GetRegistry().GetAll()) { auto props = BlockCipher::GetRegistry().GetProperties(name.c_str()); cout << _("Implementation: ") << name << "\n"; cout << "\t" << _("Provider: ") << props->library << "\n"; - cout << "\t" << _("Block cipher: ") << props->cipher << " / " - << props->mode << "\n"; + cout << "\t" << _("Block cipher: ") << props->cipher << " / " << props->mode + << "\n"; cout << "\t" << _("Key Sizes: ") << props->keySize << "\n"; } cout << "\n"; cout << _("Stream modes:\n"); - for (const string& name : StreamCipher::GetRegistry().GetAll()) { + for (const string &name : StreamCipher::GetRegistry().GetAll()) { auto props = StreamCipher::GetRegistry().GetProperties(name.c_str()); cout << _("Implementation: ") << name << "\n"; cout << "\t" << _("Provider: ") << props->library << "\n"; cout << "\t" << _("Stream cipher: ") << props->cipher << " / " - << props->mode << "\n"; + << props->mode << "\n"; cout << "\t" << _("Key Sizes: ") << props->keySize << "\n"; } cout << "\n"; - + cout << _("MAC modes:\n"); - for (const string& name : MAC::GetRegistry().GetAll()) { + for (const string &name : MAC::GetRegistry().GetAll()) { auto props = MAC::GetRegistry().GetProperties(name.c_str()); cout << _("Implementation: ") << name << "\n"; cout << "\t" << _("Provider: ") << props->library << "\n"; cout << "\t" << _("Hash mode: ") << props->hashFunction << " / " - << props->mode << "\n"; + << props->mode << "\n"; cout << "\t" << _("Block size: ") << props->blockSize << "\n"; } cout << "\n"; cout << _("PBKDF modes:\n"); - for (const string& name : PBKDF::GetRegistry().GetAll()) { + for (const string &name : PBKDF::GetRegistry().GetAll()) { auto props = PBKDF::GetRegistry().GetProperties(name.c_str()); cout << _("Implementation: ") << name << "\n"; cout << "\t" << _("Provider: ") << props->library << "\n"; @@ -218,140 +225,123 @@ static int showCiphers( int argc, char **argv ) return EXIT_SUCCESS; } -static int showInfo( int argc, char **argv ) -{ +static int showInfo(int argc, char **argv) { (void)argc; string rootDir = argv[1]; - if( !checkDir( rootDir )) - return EXIT_FAILURE; + if (!checkDir(rootDir)) return EXIT_FAILURE; EncfsConfig config; - ConfigType type = readConfig( rootDir, config ); + ConfigType type = readConfig(rootDir, config); // show information stored in config.. - switch(type) - { - case Config_None: - // xgroup(diag) - cout << _("Unable to load or parse config file\n"); - return EXIT_FAILURE; - case Config_Prehistoric: - // xgroup(diag) - cout << _("A really old EncFS filesystem was found. \n" - "It is not supported in this EncFS build.\n"); - return EXIT_FAILURE; - case Config_V3: - // xgroup(diag) - cout << "\n" << autosprintf(_("Version 3 configuration; " - "created by %s\n"), config.creator().c_str()); - break; - case Config_V4: - // xgroup(diag) - cout << "\n" << autosprintf(_("Version 4 configuration; " - "created by %s\n"), config.creator().c_str()); - break; - case Config_V5: - case Config_V6: - case Config_V7: - // xgroup(diag) - cout << "\n" << autosprintf(_("Version %i configuration; " - "created by %s (revision %i)\n"), - type, - config.creator().c_str(), - config.revision()); - break; + switch (type) { + case Config_None: + // xgroup(diag) + cout << _("Unable to load or parse config file\n"); + return EXIT_FAILURE; + case Config_Prehistoric: + // xgroup(diag) + cout << _("A really old EncFS filesystem was found. \n" + "It is not supported in this EncFS build.\n"); + return EXIT_FAILURE; + case Config_V3: + // xgroup(diag) + cout << "\n" << autosprintf(_("Version 3 configuration; " + "created by %s\n"), + config.creator().c_str()); + break; + case Config_V4: + // xgroup(diag) + cout << "\n" << autosprintf(_("Version 4 configuration; " + "created by %s\n"), + config.creator().c_str()); + break; + case Config_V5: + case Config_V6: + case Config_V7: + // xgroup(diag) + cout << "\n" + << autosprintf(_("Version %i configuration; " + "created by %s (revision %i)\n"), + type, config.creator().c_str(), config.revision()); + break; } - showFSInfo( config ); + showFSInfo(config); return EXIT_SUCCESS; } -static RootPtr initRootInfo(int &argc, char ** &argv) -{ +static RootPtr initRootInfo(int &argc, char **&argv) { RootPtr result; - shared_ptr opts( new EncFS_Opts() ); + shared_ptr opts(new EncFS_Opts()); opts->createIfNotFound = false; opts->checkKey = false; - static struct option long_options[] = { - {"extpass", 1, 0, 'p'}, - {0,0,0,0} - }; + static struct option long_options[] = {{"extpass", 1, 0, 'p'}, {0, 0, 0, 0}}; - for(;;) - { + for (;;) { int option_index = 0; - int res = getopt_long( argc, argv, "", - long_options, &option_index); - if(res == -1) - break; + int res = getopt_long(argc, argv, "", long_options, &option_index); + if (res == -1) break; - switch(res) - { - case 'p': - opts->passwordProgram.assign(optarg); - break; - default: - LOG(WARNING) << "getopt error: " << res; - break; + switch (res) { + case 'p': + opts->passwordProgram.assign(optarg); + break; + default: + LOG(WARNING) << "getopt error: " << res; + break; } } argc -= optind; argv += optind; - if(argc == 0) - { + if (argc == 0) { cerr << _("Incorrect number of arguments") << "\n"; - } else - { - opts->rootDir = string( argv[0] ); + } else { + opts->rootDir = string(argv[0]); --argc; ++argv; - if(checkDir( opts->rootDir )) - result = initFS( NULL, opts ); + if (checkDir(opts->rootDir)) result = initFS(NULL, opts); - if(!result) + if (!result) cerr << _("Unable to initialize encrypted filesystem - check path.\n"); } return result; } -static RootPtr initRootInfo(const char* crootDir) -{ +static RootPtr initRootInfo(const char *crootDir) { string rootDir(crootDir); RootPtr result; - if(checkDir( rootDir )) - { - shared_ptr opts( new EncFS_Opts() ); + if (checkDir(rootDir)) { + shared_ptr opts(new EncFS_Opts()); opts->rootDir = rootDir; opts->createIfNotFound = false; opts->checkKey = false; - result = initFS( NULL, opts ); + result = initFS(NULL, opts); } - if(!result) + if (!result) cerr << _("Unable to initialize encrypted filesystem - check path.\n"); return result; } -static int cmd_showKey( int argc, char **argv ) -{ +static int cmd_showKey(int argc, char **argv) { RootPtr rootInfo = initRootInfo(argv[1]); - if(!rootInfo) + if (!rootInfo) return EXIT_FAILURE; - else - { + else { // encode with itself - string b64Key = rootInfo->cipher->encodeAsString( rootInfo->volumeKey ); + string b64Key = rootInfo->cipher->encodeAsString(rootInfo->volumeKey); cout << b64Key << "\n"; @@ -359,86 +349,69 @@ static int cmd_showKey( int argc, char **argv ) } } -static int cmd_decode( int argc, char **argv ) -{ +static int cmd_decode(int argc, char **argv) { RootPtr rootInfo = initRootInfo(argc, argv); - if(!rootInfo) - return EXIT_FAILURE; + if (!rootInfo) return EXIT_FAILURE; - if(argc > 0) - { - for(int i=0; iroot->plainPath( argv[i] ); + if (argc > 0) { + for (int i = 0; i < argc; ++i) { + string name = rootInfo->root->plainPath(argv[i]); cout << name << "\n"; } - } else - { - char buf[PATH_MAX+1]; - while(cin.getline(buf,PATH_MAX)) - { - cout << rootInfo->root->plainPath( buf ) << "\n"; + } else { + char buf[PATH_MAX + 1]; + while (cin.getline(buf, PATH_MAX)) { + cout << rootInfo->root->plainPath(buf) << "\n"; } } return EXIT_SUCCESS; } -static int cmd_encode( int argc, char **argv ) -{ +static int cmd_encode(int argc, char **argv) { RootPtr rootInfo = initRootInfo(argc, argv); - if(!rootInfo) - return EXIT_FAILURE; + if (!rootInfo) return EXIT_FAILURE; - if(argc > 0) - { - for(int i=0; i 0) { + for (int i = 0; i < argc; ++i) { string name = rootInfo->root->cipherPathWithoutRoot(argv[i]); cout << name << "\n"; } - } else - { - char buf[PATH_MAX+1]; - while(cin.getline(buf,PATH_MAX)) - { - cout << rootInfo->root->cipherPathWithoutRoot( buf ) << "\n"; + } else { + char buf[PATH_MAX + 1]; + while (cin.getline(buf, PATH_MAX)) { + cout << rootInfo->root->cipherPathWithoutRoot(buf) << "\n"; } } return EXIT_SUCCESS; } -static int cmd_ls( int argc, char **argv ) -{ +static int cmd_ls(int argc, char **argv) { (void)argc; RootPtr rootInfo = initRootInfo(argv[1]); - if(!rootInfo) - return EXIT_FAILURE; + if (!rootInfo) return EXIT_FAILURE; // show files in directory { DirTraverse dt = rootInfo->root->openDir("/"); - if(dt.valid()) - { - for(string name = dt.nextPlaintextName(); !name.empty(); - name = dt.nextPlaintextName()) - { - shared_ptr fnode = - rootInfo->root->lookupNode( name.c_str(), "encfsctl-ls" ); + if (dt.valid()) { + for (string name = dt.nextPlaintextName(); !name.empty(); + name = dt.nextPlaintextName()) { + shared_ptr fnode = + rootInfo->root->lookupNode(name.c_str(), "encfsctl-ls"); struct stat stbuf; - fnode->getAttr( &stbuf ); + fnode->getAttr(&stbuf); struct tm stm; - localtime_r( &stbuf.st_mtime, &stm ); + localtime_r(&stbuf.st_mtime, &stm); stm.tm_year += 1900; // TODO: when I add "%s" to the end and name.c_str(), I get a // seg fault from within strlen. Why ??? - printf("%11i %4i-%02i-%02i %02i:%02i:%02i %s\n", - int(stbuf.st_size), - int(stm.tm_year), int(stm.tm_mon), int(stm.tm_mday), - int(stm.tm_hour), int(stm.tm_min), int(stm.tm_sec), - name.c_str()); + printf("%11i %4i-%02i-%02i %02i:%02i:%02i %s\n", int(stbuf.st_size), + int(stm.tm_year), int(stm.tm_mon), int(stm.tm_mday), + int(stm.tm_hour), int(stm.tm_min), int(stm.tm_sec), + name.c_str()); } } } @@ -447,83 +420,70 @@ static int cmd_ls( int argc, char **argv ) } // apply an operation to every block in the file -template -int processContents( const shared_ptr &rootInfo, - const char *path, T &op ) -{ +template +int processContents(const shared_ptr &rootInfo, const char *path, + T &op) { int errCode = 0; - shared_ptr node = rootInfo->root->openNode( path, "encfsctl", - O_RDONLY, &errCode ); + shared_ptr node = + rootInfo->root->openNode(path, "encfsctl", O_RDONLY, &errCode); - if(!node) - { + if (!node) { // try treating filename as an enciphered path - string plainName = rootInfo->root->plainPath( path ); - node = rootInfo->root->lookupNode( plainName.c_str(), "encfsctl" ); - if(node) - { - errCode = node->open( O_RDONLY ); - if(errCode < 0) - node.reset(); + string plainName = rootInfo->root->plainPath(path); + node = rootInfo->root->lookupNode(plainName.c_str(), "encfsctl"); + if (node) { + errCode = node->open(O_RDONLY); + if (errCode < 0) node.reset(); } } - if(!node) - { + if (!node) { cerr << "unable to open " << path << "\n"; return errCode; - } else - { + } else { unsigned char buf[512]; - int blocks = (node->getSize() + sizeof(buf)-1) / sizeof(buf); + int blocks = (node->getSize() + sizeof(buf) - 1) / sizeof(buf); // read all the data in blocks - for(int i=0; iread(i*sizeof(buf), buf, sizeof(buf)); + for (int i = 0; i < blocks; ++i) { + int bytes = node->read(i * sizeof(buf), buf, sizeof(buf)); int res = op(buf, bytes); - if(res < 0) - return res; + if (res < 0) return res; } } return 0; -} - -class WriteOutput -{ +} + +class WriteOutput { int _fd; -public: + + public: WriteOutput(int fd) { _fd = fd; } ~WriteOutput() { close(_fd); } - int operator()(const void *buf, int count) - { + int operator()(const void *buf, int count) { return (int)write(_fd, buf, count); } }; -static int cmd_cat( int argc, char **argv ) -{ +static int cmd_cat(int argc, char **argv) { (void)argc; RootPtr rootInfo = initRootInfo(argv[1]); - if(!rootInfo) - return EXIT_FAILURE; + if (!rootInfo) return EXIT_FAILURE; const char *path = argv[2]; WriteOutput output(STDOUT_FILENO); - int errCode = processContents( rootInfo, path, output ); + int errCode = processContents(rootInfo, path, output); return errCode; } -static int copyLink(const struct stat &stBuf, - const shared_ptr &rootInfo, - const string &cpath, const string &destName ) -{ - vector buf(stBuf.st_size+1, 0); - int res = ::readlink( cpath.c_str(), &buf[0], stBuf.st_size ); - if(res == -1) - { +static int copyLink(const struct stat &stBuf, + const shared_ptr &rootInfo, const string &cpath, + const string &destName) { + vector buf(stBuf.st_size + 1, 0); + int res = ::readlink(cpath.c_str(), &buf[0], stBuf.st_size); + if (res == -1) { cerr << "unable to readlink of " << cpath << "\n"; return EXIT_FAILURE; } @@ -531,160 +491,128 @@ static int copyLink(const struct stat &stBuf, buf[res] = '\0'; string decodedLink = rootInfo->root->plainPath(&buf[0]); - res = ::symlink( decodedLink.c_str(), destName.c_str() ); - if(res == -1) - { - cerr << "unable to create symlink for " << cpath - << " to " << decodedLink << "\n"; + res = ::symlink(decodedLink.c_str(), destName.c_str()); + if (res == -1) { + cerr << "unable to create symlink for " << cpath << " to " << decodedLink + << "\n"; } return EXIT_SUCCESS; } -static int copyContents(const shared_ptr &rootInfo, - const char* encfsName, const char* targetName) -{ - shared_ptr node = - rootInfo->root->lookupNode( encfsName, "encfsctl" ); +static int copyContents(const shared_ptr &rootInfo, + const char *encfsName, const char *targetName) { + shared_ptr node = rootInfo->root->lookupNode(encfsName, "encfsctl"); - if(!node) - { + if (!node) { cerr << "unable to open " << encfsName << "\n"; return EXIT_FAILURE; - } else - { + } else { struct stat st; - if(node->getAttr(&st) != 0) - return EXIT_FAILURE; + if (node->getAttr(&st) != 0) return EXIT_FAILURE; - if((st.st_mode & S_IFLNK) == S_IFLNK) - { + if ((st.st_mode & S_IFLNK) == S_IFLNK) { string d = rootInfo->root->cipherPath(encfsName); - char linkContents[PATH_MAX+2]; + char linkContents[PATH_MAX + 2]; - if(readlink (d.c_str(), linkContents, PATH_MAX + 1) <= 0) - { + if (readlink(d.c_str(), linkContents, PATH_MAX + 1) <= 0) { cerr << "unable to read link " << encfsName << "\n"; return EXIT_FAILURE; } - symlink(rootInfo->root->plainPath(linkContents).c_str(), - targetName); - } else - { + symlink(rootInfo->root->plainPath(linkContents).c_str(), targetName); + } else { int outfd = creat(targetName, st.st_mode); WriteOutput output(outfd); - processContents( rootInfo, encfsName, output ); + processContents(rootInfo, encfsName, output); } } return EXIT_SUCCESS; } -static bool endsWith(const string &str, char ch) -{ - if(str.empty()) +static bool endsWith(const string &str, char ch) { + if (str.empty()) return false; else - return str[str.length()-1] == ch; + return str[str.length() - 1] == ch; } -static int traverseDirs(const shared_ptr &rootInfo, - string volumeDir, string destDir) -{ - if(!endsWith(volumeDir, '/')) - volumeDir.append("/"); - if(!endsWith(destDir, '/')) - destDir.append("/"); +static int traverseDirs(const shared_ptr &rootInfo, + string volumeDir, string destDir) { + if (!endsWith(volumeDir, '/')) volumeDir.append("/"); + if (!endsWith(destDir, '/')) destDir.append("/"); // Lookup directory node so we can create a destination directory // with the same permissions { struct stat st; - shared_ptr dirNode = - rootInfo->root->lookupNode( volumeDir.c_str(), "encfsctl" ); - if(dirNode->getAttr(&st)) - return EXIT_FAILURE; + shared_ptr dirNode = + rootInfo->root->lookupNode(volumeDir.c_str(), "encfsctl"); + if (dirNode->getAttr(&st)) return EXIT_FAILURE; mkdir(destDir.c_str(), st.st_mode); } // show files in directory DirTraverse dt = rootInfo->root->openDir(volumeDir.c_str()); - if(dt.valid()) - { - for(string name = dt.nextPlaintextName(); !name.empty(); - name = dt.nextPlaintextName()) - { + if (dt.valid()) { + for (string name = dt.nextPlaintextName(); !name.empty(); + name = dt.nextPlaintextName()) { // Recurse to subdirectories - if(name != "." && name != "..") - { + if (name != "." && name != "..") { string plainPath = volumeDir + name; string cpath = rootInfo->root->cipherPath(plainPath.c_str()); string destName = destDir + name; int r = EXIT_SUCCESS; struct stat stBuf; - if( !lstat( cpath.c_str(), &stBuf )) - { - if( S_ISDIR( stBuf.st_mode ) ) - { - traverseDirs(rootInfo, (plainPath + '/').c_str(), - destName + '/'); - } else if( S_ISLNK( stBuf.st_mode )) - { - r = copyLink( stBuf, rootInfo, cpath, destName ); - } else - { - r = copyContents(rootInfo, plainPath.c_str(), - destName.c_str()); + if (!lstat(cpath.c_str(), &stBuf)) { + if (S_ISDIR(stBuf.st_mode)) { + traverseDirs(rootInfo, (plainPath + '/').c_str(), destName + '/'); + } else if (S_ISLNK(stBuf.st_mode)) { + r = copyLink(stBuf, rootInfo, cpath, destName); + } else { + r = copyContents(rootInfo, plainPath.c_str(), destName.c_str()); } - } else - { + } else { r = EXIT_FAILURE; } - if(r != EXIT_SUCCESS) - return r; + if (r != EXIT_SUCCESS) return r; } } } return EXIT_SUCCESS; } -static int cmd_export( int argc, char **argv ) -{ +static int cmd_export(int argc, char **argv) { (void)argc; RootPtr rootInfo = initRootInfo(argv[1]); - if(!rootInfo) - return EXIT_FAILURE; + if (!rootInfo) return EXIT_FAILURE; string destDir = argv[2]; // if the dir doesn't exist, then create it (with user permission) - if(!checkDir(destDir) && !userAllowMkdir(destDir.c_str(), 0700)) + if (!checkDir(destDir) && !userAllowMkdir(destDir.c_str(), 0700)) return EXIT_FAILURE; return traverseDirs(rootInfo, "/", destDir); } -int showcruft( const shared_ptr &rootInfo, const char *dirName ) -{ +int showcruft(const shared_ptr &rootInfo, const char *dirName) { int found = 0; - DirTraverse dt = rootInfo->root->openDir( dirName ); - if(dt.valid()) - { + DirTraverse dt = rootInfo->root->openDir(dirName); + if (dt.valid()) { bool showedDir = false; - for(string name = dt.nextInvalid(); !name.empty(); - name = dt.nextInvalid()) - { - string cpath = rootInfo->root->cipherPath( dirName ); + for (string name = dt.nextInvalid(); !name.empty(); + name = dt.nextInvalid()) { + string cpath = rootInfo->root->cipherPath(dirName); cpath += '/'; cpath += name; - if(!showedDir) - { + if (!showedDir) { // just before showing a list of files in a directory cout << autosprintf(_("In directory %s: \n"), dirName); showedDir = true; @@ -694,23 +622,20 @@ int showcruft( const shared_ptr &rootInfo, const char *dirName ) } // now go back and look for directories to recurse into.. - dt = rootInfo->root->openDir( dirName ); - if(dt.valid()) - { - for(string name = dt.nextPlaintextName(); !name.empty(); - name = dt.nextPlaintextName()) - { - if( name == "." || name == "..") - continue; + dt = rootInfo->root->openDir(dirName); + if (dt.valid()) { + for (string name = dt.nextPlaintextName(); !name.empty(); + name = dt.nextPlaintextName()) { + if (name == "." || name == "..") continue; string plainPath = dirName; plainPath += '/'; plainPath += name; - string cpath = rootInfo->root->cipherPath( plainPath.c_str() ); + string cpath = rootInfo->root->cipherPath(plainPath.c_str()); - if(isDirectory( cpath.c_str() )) - found += showcruft( rootInfo, plainPath.c_str() ); + if (isDirectory(cpath.c_str())) + found += showcruft(rootInfo, plainPath.c_str()); } } } @@ -722,63 +647,54 @@ int showcruft( const shared_ptr &rootInfo, const char *dirName ) iterate recursively through the filesystem and print out names of files which have filenames which cannot be decoded with the given key.. */ -static int cmd_showcruft( int argc, char **argv ) -{ +static int cmd_showcruft(int argc, char **argv) { (void)argc; RootPtr rootInfo = initRootInfo(argv[1]); - if(!rootInfo) - return EXIT_FAILURE; + if (!rootInfo) return EXIT_FAILURE; - int filesFound = showcruft( rootInfo, "/" ); + int filesFound = showcruft(rootInfo, "/"); cout << autosprintf("Found %i invalid file(s).", filesFound) << "\n"; return EXIT_SUCCESS; } -static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv ) -{ +static int do_chpasswd(bool useStdin, bool annotate, int argc, char **argv) { (void)argc; string rootDir = argv[1]; - if( !checkDir( rootDir )) - return EXIT_FAILURE; + if (!checkDir(rootDir)) return EXIT_FAILURE; EncfsConfig config; - ConfigType cfgType = readConfig( rootDir, config ); + ConfigType cfgType = readConfig(rootDir, config); - if(cfgType == Config_None) - { + if (cfgType == Config_None) { cout << _("Unable to load or parse config file\n"); return EXIT_FAILURE; } // ask for existing password cout << _("Enter current Encfs password\n"); - if (annotate) - cerr << "$PROMPT$ passwd" << endl; - CipherKey userKey = getUserKey( config, useStdin ); - if(!userKey.valid()) - return EXIT_FAILURE; + if (annotate) cerr << "$PROMPT$ passwd" << endl; + CipherKey userKey = getUserKey(config, useStdin); + if (!userKey.valid()) return EXIT_FAILURE; // instanciate proper cipher shared_ptr cipher = getCipher(config); - if(!cipher) - { + if (!cipher) { cout << autosprintf(_("Unable to find specified cipher \"%s\"\n"), - config.cipher().name().c_str()); + config.cipher().name().c_str()); return EXIT_FAILURE; } cipher->setKey(userKey); // decode volume key using user key -- at this point we detect an incorrect // password if the key checksum does not match (causing readKey to fail). - CipherKey volumeKey = cipher->readKey( - (const unsigned char *)config.key().ciphertext().data(), true ); + CipherKey volumeKey = cipher->readKey( + (const unsigned char *)config.key().ciphertext().data(), true); - if(!volumeKey.valid()) - { + if (!volumeKey.valid()) { cout << _("Invalid password\n"); return EXIT_FAILURE; } @@ -790,42 +706,36 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv ) cout << _("Enter new Encfs password\n"); // create new key - if( useStdin ) - { - if (annotate) - cerr << "$PROMPT$ new_passwd" << endl; + if (useStdin) { + if (annotate) cerr << "$PROMPT$ new_passwd" << endl; } - userKey = getNewUserKey( config, useStdin, string(), string() ); + userKey = getNewUserKey(config, useStdin, string(), string()); // re-encode the volume key using the new user key and write it out.. int result = EXIT_FAILURE; - if(userKey.valid()) - { + if (userKey.valid()) { int encodedKeySize = cipher->encodedKeySize(); - unsigned char *keyBuf = new unsigned char[ encodedKeySize ]; + unsigned char *keyBuf = new unsigned char[encodedKeySize]; // encode volume key with new user key cipher->setKey(userKey); - cipher->writeKey( volumeKey, keyBuf ); + cipher->writeKey(volumeKey, keyBuf); userKey.reset(); cipher->setKey(volumeKey); EncryptedKey *key = config.mutable_key(); - key->set_ciphertext( keyBuf, encodedKeySize ); + key->set_ciphertext(keyBuf, encodedKeySize); delete[] keyBuf; - if(saveConfig( rootDir, config )) - { + if (saveConfig(rootDir, config)) { // password modified -- changes volume key of filesystem.. cout << _("Volume Key successfully updated.\n"); result = EXIT_SUCCESS; - } else - { + } else { cout << _("Error saving modified config file.\n"); } - } else - { + } else { cout << _("Error creating key\n"); } @@ -834,19 +744,15 @@ static int do_chpasswd( bool useStdin, bool annotate, int argc, char **argv ) return result; } -static int chpasswd( int argc, char **argv ) -{ - return do_chpasswd( false, false, argc, argv ); +static int chpasswd(int argc, char **argv) { + return do_chpasswd(false, false, argc, argv); } -static int chpasswdAutomaticly( int argc, char **argv ) -{ - return do_chpasswd( true, false, argc, argv ); +static int chpasswdAutomaticly(int argc, char **argv) { + return do_chpasswd(true, false, argc, argv); } - -int main(int argc, char **argv) -{ +int main(int argc, char **argv) { FLAGS_logtostderr = 1; FLAGS_minloglevel = 1; @@ -858,42 +764,35 @@ int main(int argc, char **argv) google::InstallFailureSignalHandler(); #ifdef LOCALEDIR - setlocale( LC_ALL, "" ); - bindtextdomain( PACKAGE, LOCALEDIR ); - textdomain( PACKAGE ); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); #endif bool isThreaded = false; CipherV1::init(isThreaded); - if(argc < 2) - { - usage( argv[0] ); + if (argc < 2) { + usage(argv[0]); return EXIT_FAILURE; } // find the specified command int offset = 0; - while(commands[offset].name != 0) - { - if(!strcmp( argv[1], commands[offset].name )) - break; + while (commands[offset].name != 0) { + if (!strcmp(argv[1], commands[offset].name)) break; ++offset; } - if(commands[offset].name == 0) - { + if (commands[offset].name == 0) { cerr << autosprintf(_("invalid command: \"%s\""), argv[1]) << "\n"; - } else - { - if((argc-2 < commands[offset].minOptions) || - (argc-2 > commands[offset].maxOptions)) - { - cerr << autosprintf( - _("Incorrect number of arguments for command \"%s\""), - argv[1]) << "\n"; + } else { + if ((argc - 2 < commands[offset].minOptions) || + (argc - 2 > commands[offset].maxOptions)) { + cerr << autosprintf(_("Incorrect number of arguments for command \"%s\""), + argv[1]) << "\n"; } else - return (*commands[offset].func)( argc-1, argv+1 ); + return (*commands[offset].func)(argc - 1, argv + 1); } CipherV1::shutdown(isThreaded); diff --git a/util/makeKey.cpp b/util/makeKey.cpp index fb93585..737511c 100644 --- a/util/makeKey.cpp +++ b/util/makeKey.cpp @@ -4,10 +4,10 @@ ***************************************************************************** * Copyright (c) 2008, Valient Gough * - * This program is free software: you can redistribute it and/or modify it + * 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. + * (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 @@ -29,36 +29,32 @@ #include #include -void genKey( const shared_ptr &cipher ) -{ - CipherKey key = cipher->newRandomKey(); +void genKey(const shared_ptr &cipher) { + CipherKey key = cipher->newRandomKey(); - // encode with itself - string b64Key = cipher->encodeAsString( key, key ); + // encode with itself + string b64Key = cipher->encodeAsString(key, key); - cout << b64Key << "\n"; + cout << b64Key << "\n"; } -int main(int argc, char **argv) -{ - pid_t pid = getpid(); - cerr << "pid = " << pid << "\n"; +int main(int argc, char **argv) { + pid_t pid = getpid(); + cerr << "pid = " << pid << "\n"; - if(argc != 3) - { - cerr << "usage: makeKey [AES|Blowfish] [128|160|192|224|256]\n"; - return 1; - } + if (argc != 3) { + cerr << "usage: makeKey [AES|Blowfish] [128|160|192|224|256]\n"; + return 1; + } - const char *type = argv[1]; - int size = atoi(argv[2]); + const char *type = argv[1]; + int size = atoi(argv[2]); - openssl_init(false); + openssl_init(false); - // get a list of the available algorithms - shared_ptr cipher = Cipher::New( type, size ); - genKey( cipher ); - - //openssl_shutdown(false); -} + // get a list of the available algorithms + shared_ptr cipher = Cipher::New(type, size); + genKey(cipher); + // openssl_shutdown(false); +}