├── configure ├── devmode ├── base ├── Error.cpp ├── types.h ├── Error.h ├── CMakeLists.txt ├── config.h.cmake ├── shared_ptr.h ├── i18n.h ├── Interface.h ├── ConfigReader.h ├── XmlReader.h ├── Mutex.h ├── autosprintf.cpp ├── autosprintf.h ├── ConfigVar.h ├── Registry.h ├── Interface.cpp ├── base64.h ├── Range.h ├── ConfigReader.cpp ├── XmlReader.cpp └── ConfigVar.cpp ├── COPYING ├── cipher ├── MAC.cpp ├── PBKDF.cpp ├── StreamCipher.cpp ├── BlockCipher.cpp ├── BlockCipher.h ├── MAC.h ├── CommonCrypto.h ├── NullCiphers.h ├── PBKDF.h ├── botan.h ├── CipherKey_test.cpp ├── openssl.h ├── CMakeLists.txt ├── testing.h ├── testing.cpp ├── CipherKey.h ├── NullCiphers.cpp ├── CipherKey.cpp ├── StreamCipher.h ├── MemoryPool.h ├── readpassphrase.h ├── MAC_test.cpp ├── PBKDF_test.cpp ├── MemoryPool.cpp └── readpassphrase.cpp ├── AUTHORS ├── po ├── POTFILES.in ├── CMakeLists.txt └── Makevars ├── README-NLS ├── protos ├── interface.proto └── fsconfig.proto ├── dk2ChangeLog ├── fs ├── testing.h ├── FileIO.cpp ├── CMakeLists.txt ├── testextpass ├── MemFileIO.h ├── NullNameIO.h ├── NameIO_test.cpp ├── MemBlockFileIO.h ├── RawFileIO.h ├── StreamNameIO.h ├── BlockFileIO_test.cpp ├── MACFileIO.h ├── NullNameIO.cpp ├── MemBlockFileIO.cpp ├── BlockNameIO.h ├── BlockFileIO.h ├── FileIO.h ├── MemFileIO.cpp ├── FSConfig.h ├── CipherFileIO.h ├── FileNode.h ├── Context.h ├── IO_test.cpp ├── NameIO.h ├── encfs.h ├── FileUtils.h ├── Context.cpp ├── DirNode.h ├── StreamNameIO.cpp └── testing.cpp ├── CMakeModules ├── OpenSSLTests.cmake ├── FindTinyXML.cmake ├── FindFUSE.cmake ├── FindGFlags.cmake ├── FindBotan.cmake └── FindGLog.cmake ├── INSTALL ├── encfs └── CMakeLists.txt ├── util ├── CMakeLists.txt ├── encfssh ├── makeKey.cpp └── encfsctl.pod └── CMakeLists.txt /configure: -------------------------------------------------------------------------------- 1 | cmake . -DCMAKE_BUILD_TYPE=Release $@ 2 | -------------------------------------------------------------------------------- /devmode: -------------------------------------------------------------------------------- 1 | mkdir build 2 | cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug $@ 3 | -------------------------------------------------------------------------------- /base/Error.cpp: -------------------------------------------------------------------------------- 1 | #include "base/Error.h" 2 | 3 | namespace encfs { 4 | 5 | Error::Error(const char *msg) : runtime_error(msg) {} 6 | 7 | } // namespace encfs 8 | -------------------------------------------------------------------------------- /base/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | namespace encfs { 5 | 6 | typedef unsigned char byte; 7 | } 8 | 9 | #endif // TYPES_H 10 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | 2 | For portions of Encfs which are licensed under the LGPL: see COPYING.LGPL. 3 | For portions of Encfs which are licensed under the GPL: see COPYING.GPL. 4 | 5 | -------------------------------------------------------------------------------- /cipher/MAC.cpp: -------------------------------------------------------------------------------- 1 | #include "cipher/MAC.h" 2 | 3 | namespace encfs { 4 | 5 | DEFINE_REGISTERABLE_TYPE(MAC) 6 | 7 | MAC::MAC() {} 8 | 9 | MAC::~MAC() {} 10 | 11 | } // namespace encfs 12 | -------------------------------------------------------------------------------- /cipher/PBKDF.cpp: -------------------------------------------------------------------------------- 1 | #include "cipher/PBKDF.h" 2 | 3 | namespace encfs { 4 | 5 | DEFINE_REGISTERABLE_TYPE(PBKDF) 6 | 7 | PBKDF::PBKDF() {} 8 | 9 | PBKDF::~PBKDF() {} 10 | 11 | } // namespace encfs 12 | -------------------------------------------------------------------------------- /cipher/StreamCipher.cpp: -------------------------------------------------------------------------------- 1 | #include "cipher/StreamCipher.h" 2 | 3 | namespace encfs { 4 | 5 | DEFINE_REGISTERABLE_TYPE(StreamCipher); 6 | 7 | StreamCipher::StreamCipher() {} 8 | 9 | StreamCipher::~StreamCipher() {} 10 | 11 | } // namespace encfs 12 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | 2 | Valient Gough 3 | 4 | 5 | With significant contributions from: 6 | 7 | Csaba Henk 8 | David Rosenstrauch 9 | Gerald Klix 10 | Janne Hellsten 11 | p.kosseff 12 | 13 | 14 | Also, thanks to the work of many contributors, encfs has full or partial 15 | translations for many languages. See README-NLS for more details. 16 | 17 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # For updating this file, look at the result of: 2 | # $ head -3 po/POTFILES.in > /tmp/POTFILES.in && grep -l 'i18n.h' ../*.{cpp,h}* >> /tmp/POTFILES.in && cp -f /tmp/POTFILES.in po/ 3 | 4 | ../cipher/SSL_Cipher.cpp 5 | ../encfs/main.cpp 6 | ../fs/BlockFileIO.cpp 7 | ../fs/BlockNameIO.cpp 8 | ../fs/FileUtils.cpp 9 | ../fs/MACFileIO.cpp 10 | ../fs/StreamNameIO.cpp 11 | ../util/encfsctl.cpp 12 | -------------------------------------------------------------------------------- /README-NLS: -------------------------------------------------------------------------------- 1 | 2 | EncFS is registered with Rosetta - an online interface for supplying 3 | translations. See https://translations.launchpad.net/encfs 4 | 5 | If your language is not included in this distribution, you may want 6 | to check if translated text is already available online in Rosetta. 7 | If not, consider translating some of the strings, which will then be 8 | included in the next EncFS release. 9 | 10 | 11 | -------------------------------------------------------------------------------- /protos/interface.proto: -------------------------------------------------------------------------------- 1 | 2 | package encfs; 3 | 4 | option optimize_for = CODE_SIZE; 5 | 6 | message Interface 7 | { 8 | required string name = 1; 9 | required uint32 major = 2; // major version number 10 | required uint32 minor = 3; // minor version number 11 | 12 | // Age indicates number of major versions supported. 0 means no backward 13 | // compatibility. See libtool "updating version information" for more 14 | // details on how major/minor/age are used for versioning libraries. 15 | optional uint32 age = 4; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /dk2ChangeLog: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | use strict; 4 | 5 | open(LOG, "darcs changes|") || die "Can't open 'dk changes': $!"; 6 | 7 | my $lastDate = ""; 8 | while() 9 | { 10 | if( /^(\w+)\s+(\w+)\s+(\d+)\s+([0-9:]+)\s+(\w+)\s+(\d+)\s+(.*)$/ ) 11 | { 12 | my $date = "$1 $2 $3 $6"; 13 | if($date ne $lastDate) 14 | { 15 | $lastDate = $date; 16 | print "$date $7\n"; 17 | } 18 | } else 19 | { 20 | s/^\s+//; 21 | if(/\w/) 22 | { 23 | print "\t$_"; 24 | } else 25 | { 26 | #print "\n"; 27 | } 28 | } 29 | } 30 | 31 | close(LOG) 32 | 33 | -------------------------------------------------------------------------------- /base/Error.h: -------------------------------------------------------------------------------- 1 | #ifndef _Error_incl_ 2 | #define _Error_incl_ 3 | 4 | #include 5 | #include 6 | 7 | namespace encfs { 8 | 9 | class Error : public std::runtime_error { 10 | public: 11 | Error(const char *msg); 12 | }; 13 | 14 | #define STR(X) #X 15 | 16 | #define rAssert(cond) \ 17 | do { \ 18 | if ((cond) == false) { \ 19 | LOG(ERROR) << "Assert failed: " << STR(cond); \ 20 | throw Error(STR(cond)); \ 21 | } \ 22 | } while (0) 23 | 24 | } // namespace encfs 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /fs/testing.h: -------------------------------------------------------------------------------- 1 | #ifndef _TESTING_incl_ 2 | #define _TESTING_incl_ 3 | 4 | #include 5 | 6 | #include "cipher/CipherV1.h" 7 | #include "fs/FileUtils.h" 8 | #include "fs/FSConfig.h" 9 | 10 | namespace encfs { 11 | 12 | class FileIO; 13 | 14 | FSConfigPtr makeConfig(const shared_ptr& cipher, int blockSize); 15 | 16 | void runWithCipher(const std::string& cipherName, int blockSize, 17 | void (*func)(FSConfigPtr& config)); 18 | void runWithAllCiphers(void (*func)(FSConfigPtr& config)); 19 | 20 | void comparisonTest(FSConfigPtr& cfg, FileIO* a, FileIO* b); 21 | 22 | void compare(FileIO* a, FileIO* b, int offset, int len); 23 | 24 | } // namespace encfs 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /CMakeModules/OpenSSLTests.cmake: -------------------------------------------------------------------------------- 1 | 2 | include (CheckFunctionExists) 3 | 4 | set (CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES}) 5 | set (CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR}) 6 | 7 | check_function_exists (EVP_bf_cbc HAVE_EVP_BF) 8 | if (NOT HAVE_EVP_BF) 9 | message (STATUS " Blowfish support disabled.") 10 | endif (NOT HAVE_EVP_BF) 11 | 12 | check_function_exists (EVP_aes_128_cbc HAVE_EVP_AES) 13 | if (NOT HAVE_EVP_AES) 14 | message (STATUS " AES support disabled.") 15 | endif (NOT HAVE_EVP_AES) 16 | 17 | check_function_exists (EVP_aes_128_xts HAVE_EVP_AES_XTS) 18 | if (NOT HAVE_EVP_AES_XTS) 19 | message (STATUS " AES/XTS support disabled.") 20 | endif (NOT HAVE_EVP_AES_XTS) 21 | 22 | set (CMAKE_REQUIRED_LIBRARIES) 23 | set (CMAKE_REQUIRED_INCLUDES) 24 | 25 | -------------------------------------------------------------------------------- /base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package (TinyXML REQUIRED) 2 | include_directories (${TINYXML_INCLUDE_DIR}) 3 | set (LIBS ${LIBS} ${TINYXML_LIBRARIES}) 4 | 5 | find_package (Protobuf REQUIRED) 6 | 7 | 8 | protobuf_generate_cpp (PROTO_SRCS PROTO_HDRS ${Encfs_SOURCE_DIR}/protos/interface.proto) 9 | 10 | configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake 11 | ${CMAKE_CURRENT_BINARY_DIR}/config.h) 12 | 13 | add_library (encfs-base 14 | autosprintf.cpp 15 | base64.cpp 16 | ConfigReader.cpp 17 | ConfigVar.cpp 18 | Error.cpp 19 | Interface.cpp 20 | Range.h 21 | Registry.h 22 | XmlReader.cpp 23 | ${PROTO_SRCS} 24 | ${PROTO_HDRS} 25 | ) 26 | 27 | target_link_libraries (encfs-base 28 | ${PROTOBUF_LIBRARY} 29 | ${TINYXML_LIBRARIES} 30 | ) 31 | 32 | -------------------------------------------------------------------------------- /base/config.h.cmake: -------------------------------------------------------------------------------- 1 | #define VERSION "@ENCFS_VERSION@" 2 | 3 | #cmakedefine HAVE_ATTR_XATTR_H 4 | #cmakedefine HAVE_SYS_XATTR_H 5 | #cmakedefine XATTR_ADD_OPT 6 | #cmakedefine HAVE_COMMON_CRYPTO 7 | 8 | #cmakedefine HAVE_TR1_MEMORY 9 | #cmakedefine HAVE_TR1_UNORDERED_MAP 10 | #cmakedefine HAVE_TR1_UNORDERED_SET 11 | #cmakedefine HAVE_TR1_TUPLE 12 | 13 | #cmakedefine HAVE_VALGRIND_VALGRIND_H 14 | #cmakedefine HAVE_VALGRIND_MEMCHECK_H 15 | 16 | #cmakedefine WITH_OPENSSL 17 | #cmakedefine WITH_COMMON_CRYPTO 18 | #cmakedefine WITH_BOTAN 19 | #cmakedefine HAVE_SEC_RANDOM_H 20 | 21 | #cmakedefine HAVE_EVP_BF 22 | #cmakedefine HAVE_EVP_AES 23 | #cmakedefine HAVE_EVP_AES_XTS 24 | 25 | #cmakedefine HAVE_LCHMOD 26 | 27 | /* TODO: add other thread library support. */ 28 | #cmakedefine CMAKE_USE_PTHREADS_INIT 29 | 30 | -------------------------------------------------------------------------------- /cipher/BlockCipher.cpp: -------------------------------------------------------------------------------- 1 | #include "cipher/BlockCipher.h" 2 | 3 | #include "base/config.h" 4 | 5 | #ifdef WITH_OPENSSL 6 | #include "cipher/openssl.h" 7 | #endif 8 | #ifdef WITH_COMMON_CRYPTO 9 | #include "cipher/CommonCrypto.h" 10 | #endif 11 | 12 | #include "cipher/NullCiphers.h" 13 | 14 | namespace encfs { 15 | 16 | Registry& BlockCipher::GetRegistry() { 17 | static Registry registry; 18 | static bool first = true; 19 | if (first) { 20 | #ifdef WITH_OPENSSL 21 | OpenSSL::registerCiphers(); 22 | #endif 23 | #ifdef WITH_COMMON_CRYPTO 24 | CommonCrypto::registerCiphers(); 25 | #endif 26 | NullCiphers::registerCiphers(); 27 | first = false; 28 | } 29 | return registry; 30 | } 31 | 32 | BlockCipher::BlockCipher() {} 33 | 34 | BlockCipher::~BlockCipher() {} 35 | 36 | } // namespace encfs 37 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | 3 | Encfs uses the GNU autoconf / automake toolchain to create makefiles. 4 | 5 | The configure script is automatically generated, but is part of most EncFS 6 | distributions. If you have a distribution that does not contain the configure 7 | script, then you can generate it by running "autoreconf -if" or by running 8 | "make -f Makefile.dist". 9 | 10 | To build encfs, run: 11 | 12 | ./configure 13 | make 14 | 15 | This creates two executables, encfs and encfsctl in the encfs directory. You 16 | can install to in a system directory via "make install". If the default path 17 | (/usr/local) is not where you want things installed, then use the "--prefix" 18 | option to configure to specify the install prefix. 19 | 20 | Encfs and encfsctl can also be installed by hand. They need no special 21 | permissions. You may also want the man pages encfs.1 and encfsctl.1. 22 | 23 | 24 | -------------------------------------------------------------------------------- /cipher/BlockCipher.h: -------------------------------------------------------------------------------- 1 | #ifndef BLOCKCIPHER_H 2 | #define BLOCKCIPHER_H 3 | 4 | #include "base/Interface.h" 5 | #include "base/Range.h" 6 | #include "base/Registry.h" 7 | #include "base/shared_ptr.h" 8 | #include "base/types.h" 9 | #include "cipher/StreamCipher.h" 10 | 11 | namespace encfs { 12 | 13 | static const char NAME_AES_CBC[] = "AES/CBC"; 14 | static const char NAME_BLOWFISH_CBC[] = "Blowfish/CBC"; 15 | 16 | // BlockCipher is a StreamCipher with a block size. 17 | // Encryption and decryption must be in multiples of the block size. 18 | class BlockCipher : public StreamCipher { 19 | public: 20 | DECLARE_REGISTERABLE_TYPE(BlockCipher); 21 | 22 | BlockCipher(); 23 | virtual ~BlockCipher(); 24 | 25 | // Not valid until a key has been set, as they key size may determine the 26 | // block size. 27 | virtual int blockSize() const = 0; 28 | }; 29 | 30 | } // namespace encfs 31 | 32 | #endif // BLOCKCIPHER_H 33 | -------------------------------------------------------------------------------- /CMakeModules/FindTinyXML.cmake: -------------------------------------------------------------------------------- 1 | # - Find TinyXML 2 | # Find the native TinyXML includes and library 3 | # 4 | # TINYXML_FOUND - True if TinyXML found. 5 | # TINYXML_INCLUDE_DIR - where to find tinyxml.h, etc. 6 | # TINYXML_LIBRARIES - List of libraries when using TinyXML. 7 | # 8 | 9 | IF( TINYXML_INCLUDE_DIR ) 10 | # Already in cache, be silent 11 | SET( TinyXML_FIND_QUIETLY TRUE ) 12 | ENDIF( TINYXML_INCLUDE_DIR ) 13 | 14 | FIND_PATH( TINYXML_INCLUDE_DIR "tinyxml.h" 15 | PATH_SUFFIXES "tinyxml" ) 16 | 17 | FIND_LIBRARY( TINYXML_LIBRARIES 18 | NAMES "tinyxml" 19 | PATH_SUFFIXES "tinyxml" ) 20 | 21 | # handle the QUIETLY and REQUIRED arguments and set TINYXML_FOUND to TRUE if 22 | # all listed variables are TRUE 23 | INCLUDE( "FindPackageHandleStandardArgs" ) 24 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( "TinyXML" DEFAULT_MSG TINYXML_INCLUDE_DIR TINYXML_LIBRARIES ) 25 | 26 | MARK_AS_ADVANCED( TINYXML_INCLUDE_DIR TINYXML_LIBRARIES ) 27 | -------------------------------------------------------------------------------- /encfs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories (${Encfs_SOURCE_DIR}/base) 3 | link_directories (${Encfs_BINARY_DIR}/base) 4 | 5 | include_directories (${Encfs_SOURCE_DIR}/cipher) 6 | link_directories (${Encfs_BINARY_DIR}/cipher) 7 | 8 | include_directories (${Encfs_SOURCE_DIR}/fs) 9 | link_directories (${Encfs_BINARY_DIR}/fs) 10 | 11 | include_directories (${CMAKE_BINARY_DIR}/base) 12 | 13 | add_executable (encfs 14 | main.cpp) 15 | target_link_libraries (encfs 16 | encfs-fs 17 | encfs-cipher 18 | encfs-base 19 | ${GLOG_LIBRARIES} 20 | ${FUSE_LIBRARIES} 21 | ) 22 | 23 | if (POD2MAN) 24 | add_custom_target(man ALL 25 | COMMAND ${POD2MAN} -u --section=1 --release=${ENCFS_VERSION} 26 | --center="Encrypted Filesystem" 27 | ${CMAKE_CURRENT_SOURCE_DIR}/encfs.pod 28 | encfs.1) 29 | install (FILES ${CMAKE_CURRENT_BINARY_DIR}/encfs.1 30 | DESTINATION 31 | share/man/man1) 32 | endif (POD2MAN) 33 | 34 | install (TARGETS encfs DESTINATION bin) 35 | 36 | -------------------------------------------------------------------------------- /util/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | include_directories (${Encfs_SOURCE_DIR}/base) 3 | link_directories (${Encfs_BINARY_DIR}/base) 4 | 5 | include_directories (${Encfs_SOURCE_DIR}/cipher) 6 | link_directories (${Encfs_BINARY_DIR}/cipher) 7 | 8 | include_directories (${Encfs_SOURCE_DIR}/fs) 9 | link_directories (${Encfs_BINARY_DIR}/fs) 10 | 11 | include_directories (${CMAKE_BINARY_DIR}/base) 12 | 13 | 14 | add_executable (encfsctl 15 | encfsctl.cpp) 16 | target_link_libraries (encfsctl 17 | encfs-fs 18 | encfs-cipher 19 | encfs-base 20 | ${GLOG_LIBRARIES} 21 | ) 22 | 23 | if (POD2MAN) 24 | add_custom_target(util-man ALL 25 | COMMAND ${POD2MAN} -u --section=1 --release=${ENCFS_VERSION} 26 | --center="Encrypted Filesystem" 27 | ${CMAKE_CURRENT_SOURCE_DIR}/encfsctl.pod 28 | encfsctl.1) 29 | install (FILES ${CMAKE_CURRENT_BINARY_DIR}/encfsctl.1 30 | DESTINATION 31 | share/man/man1) 32 | endif (POD2MAN) 33 | 34 | install (TARGETS encfsctl DESTINATION bin) 35 | 36 | -------------------------------------------------------------------------------- /CMakeModules/FindFUSE.cmake: -------------------------------------------------------------------------------- 1 | # Find the FUSE includes and library 2 | # 3 | # FUSE_INCLUDE_DIR - where to find fuse.h, etc. 4 | # FUSE_LIBRARIES - List of libraries when using FUSE. 5 | # FUSE_FOUND - True if FUSE lib is found. 6 | 7 | # check if already in cache, be silent 8 | IF (FUSE_INCLUDE_DIR) 9 | SET (FUSE_FIND_QUIETLY TRUE) 10 | ENDIF (FUSE_INCLUDE_DIR) 11 | 12 | # find includes 13 | FIND_PATH (FUSE_INCLUDE_DIR fuse.h 14 | /usr/local/include/osxfuse 15 | /usr/local/include 16 | /usr/include 17 | ) 18 | 19 | # find lib 20 | if (APPLE) 21 | SET(FUSE_NAMES libosxfuse.dylib fuse) 22 | else (APPLE) 23 | SET(FUSE_NAMES fuse) 24 | endif (APPLE) 25 | FIND_LIBRARY(FUSE_LIBRARIES 26 | NAMES ${FUSE_NAMES} 27 | PATHS /lib64 /lib /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib 28 | ) 29 | 30 | include ("FindPackageHandleStandardArgs") 31 | find_package_handle_standard_args ("FUSE" DEFAULT_MSG 32 | FUSE_INCLUDE_DIR FUSE_LIBRARIES) 33 | 34 | mark_as_advanced (FUSE_INCLUDE_DIR FUSE_LIBRARIES) 35 | 36 | -------------------------------------------------------------------------------- /cipher/MAC.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCFS_MAC_H 2 | #define ENCFS_MAC_H 3 | 4 | #include 5 | 6 | #include "base/Registry.h" 7 | #include "base/types.h" 8 | #include "cipher/CipherKey.h" 9 | 10 | namespace encfs { 11 | 12 | static const char NAME_SHA1_HMAC[] = "SHA-1/HMAC"; 13 | 14 | // MAC provides keyed MessageAuthenticationCode algorithms, eg HMAC. 15 | class MAC { 16 | public: 17 | DECLARE_REGISTERABLE_TYPE(MAC); 18 | 19 | struct Properties { 20 | int blockSize; // Block length of hash function. 21 | std::string hashFunction; 22 | std::string mode; 23 | std::string library; 24 | 25 | std::string toString() const { return hashFunction + "/" + mode; } 26 | }; 27 | 28 | MAC(); 29 | virtual ~MAC(); 30 | 31 | virtual int outputSize() const = 0; 32 | 33 | virtual bool setKey(const CipherKey &key) = 0; 34 | 35 | // Init must be called before any calls to update. 36 | virtual void init() = 0; 37 | virtual bool update(const byte *in, int length) = 0; 38 | virtual bool write(byte *out) = 0; 39 | }; 40 | 41 | } // namespace encfs 42 | 43 | #endif // ENCFS_MAC_H 44 | -------------------------------------------------------------------------------- /protos/fsconfig.proto: -------------------------------------------------------------------------------- 1 | 2 | package encfs; 3 | 4 | option optimize_for = CODE_SIZE; 5 | 6 | import "interface.proto"; 7 | 8 | message EncfsConfig 9 | { 10 | optional string creator = 1; 11 | optional string writer = 11; 12 | optional int32 revision = 2 [default=0]; 13 | 14 | required Interface cipher = 3; 15 | required EncryptedKey key = 4; 16 | 17 | optional Interface naming = 5; 18 | optional bool unique_iv = 51 [default=false]; 19 | optional bool chained_iv = 52 [default=false]; 20 | optional bool external_iv = 53 [default=false]; 21 | 22 | required int32 block_size = 6; 23 | optional int32 block_mac_bytes = 61 [default=0]; 24 | optional int32 block_mac_rand_bytes = 611 [default=0]; 25 | optional bool allow_holes = 62 [default = false]; 26 | 27 | } 28 | 29 | message EncryptedKey 30 | { 31 | required bytes ciphertext = 1; 32 | required int32 size = 2; // Size of data in bytes 33 | 34 | optional bytes salt = 6; 35 | 36 | optional int32 kdf_iterations = 10; 37 | optional int32 kdf_duration = 11 [default=500]; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /cipher/CommonCrypto.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _COMMONCRYPTO_incl_ 23 | #define _COMMONCRYPTO_incl_ 24 | 25 | namespace encfs { 26 | 27 | struct CommonCrypto { 28 | static void registerCiphers(); 29 | }; 30 | 31 | } // namespace encfs 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /cipher/NullCiphers.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _NULLCIPHERS_incl_ 23 | #define _NULLCIPHERS_incl_ 24 | 25 | #include "base/Registry.h" 26 | 27 | namespace encfs { 28 | 29 | class NullCiphers { 30 | public: 31 | static void registerCiphers(); 32 | }; 33 | 34 | } // namespace encfs 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /po/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | file (GLOB PO_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.po") 3 | file (GLOB CXX_FILES RELATIVE ${PROJECT_SOURCE_DIR} "*/*.cpp") 4 | 5 | set (GettextTranslate_GMO_BINARY true) 6 | 7 | include (GettextTranslate) 8 | 9 | 10 | 11 | #find_package (Gettext REQUIRED) 12 | #find_program (GETTEXT_XGETTEXT_EXE xgettext) 13 | # 14 | #if (NOT GETTEXT_FOUND) 15 | # message (STATUS " Gettext not found") 16 | #endif (NOT GETTEXT_FOUND) 17 | #if (NOT GETTEXT_XGETTEXT_EXE) 18 | # message (STATUS " Can't find xgettext") 19 | #endif (NOT GETTEXT_XGETTEXT_EXE) 20 | # 21 | # 22 | #if (GETTEXT_FOUND AND GETTEXT_XGETTEXT_EXE) 23 | # add_custom_command( 24 | # OUTPUT ${PROJECT_NAME}.pot 25 | # COMMAND ${GETTEXT_XGETTEXT_EXE} --omit-header --keyword=_ --keyword=N_ ${CXX_FILES} -o ${PROJECT_NAME}.pot 26 | # ) 27 | # 28 | # if (PO_FILES) 29 | # message (STATUS "Translations will be built!") 30 | # gettext_create_translations (${PROJECT_NAME}.pot ALL ${PO_FILES}) 31 | # else (PO_FILES) 32 | # message (STATUS "Translations not found!") 33 | # endif (PO_FILES) 34 | #else (GETTEXT_FOUND AND GETTEXT_XGETTEXT_EXE) 35 | # message (STATUS "Translations won't be built.") 36 | #endif (GETTEXT_FOUND AND GETTEXT_XGETTEXT_EXE) 37 | 38 | -------------------------------------------------------------------------------- /fs/FileIO.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "fs/FileIO.h" 22 | 23 | namespace encfs { 24 | 25 | FileIO::FileIO() {} 26 | 27 | FileIO::~FileIO() {} 28 | 29 | int FileIO::blockSize() const { return 1; } 30 | 31 | bool FileIO::setIV(uint64_t iv) { 32 | (void)iv; 33 | return true; 34 | } 35 | 36 | } // namespace encfs 37 | -------------------------------------------------------------------------------- /cipher/PBKDF.h: -------------------------------------------------------------------------------- 1 | #ifndef ENCFS_PBKDF_H 2 | #define ENCFS_PBKDF_H 3 | 4 | #include 5 | 6 | #include "base/Registry.h" 7 | #include "base/types.h" 8 | #include "cipher/CipherKey.h" 9 | 10 | namespace encfs { 11 | 12 | // Well-known algorithms. 13 | static const char NAME_PBKDF2_HMAC_SHA1[] = "PBKDF2_HMAC_SHA1"; 14 | static const char NAME_PBKDF2_HMAC_SHA256[] = "PBKDF2_HMAC_SHA256"; 15 | 16 | // Password Based Key Derivation Function. 17 | class PBKDF { 18 | public: 19 | DECLARE_REGISTERABLE_TYPE(PBKDF); 20 | 21 | struct Properties { 22 | std::string mode; 23 | std::string library; 24 | 25 | std::string toString() const { return mode; } 26 | }; 27 | 28 | PBKDF(); 29 | virtual ~PBKDF(); 30 | 31 | virtual bool makeKey(const char *password, int passwordLength, 32 | const byte *salt, int saltLength, int numIterations, 33 | CipherKey *outKey) = 0; 34 | 35 | // Create a new key with strong randomization. 36 | virtual CipherKey randomKey(int length) = 0; 37 | 38 | // Randomize the output. Pseudo randomization is allowed, so this may not be 39 | // used for keys or other critical values. 40 | virtual bool pseudoRandom(byte *out, int byteLen) = 0; 41 | }; 42 | 43 | } // namespace encfs 44 | 45 | #endif // ENCFS_PBKDF_H 46 | -------------------------------------------------------------------------------- /cipher/botan.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _CIPHER_BOTAN_incl_ 23 | #define _CIPHER_BOTAN_incl_ 24 | 25 | #include "base/Registry.h" 26 | 27 | namespace encfs { 28 | 29 | extern void Botan_init(bool threaded); 30 | extern void Botan_shutdown(); 31 | extern void Botan_registerCiphers(); 32 | 33 | } // namespace encfs 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /cipher/CipherKey_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | #include 5 | 6 | #include "base/config.h" 7 | #include "base/shared_ptr.h" 8 | #include "cipher/CipherV1.h" 9 | #include "cipher/MemoryPool.h" 10 | #include "cipher/testing.h" 11 | 12 | #ifdef HAVE_VALGRIND_MEMCHECK_H 13 | #include 14 | #endif 15 | 16 | using namespace encfs; 17 | using std::list; 18 | using std::string; 19 | 20 | namespace { 21 | 22 | class CipherKeyTest : public testing::Test { 23 | protected: 24 | virtual void SetUp() { CipherV1::init(false); } 25 | }; 26 | 27 | TEST_F(CipherKeyTest, ReadWrite) { 28 | for (auto alg : CipherV1::GetAlgorithmList()) { 29 | auto cipher = CipherV1::New(alg.iface); 30 | ASSERT_FALSE(!cipher); 31 | 32 | CipherKey masterKey = cipher->newRandomKey(); 33 | CipherKey volumeKey = cipher->newRandomKey(); 34 | 35 | int encodedSize = cipher->encodedKeySize(); 36 | unsigned char *keyBuf = new unsigned char[encodedSize]; 37 | 38 | cipher->setKey(masterKey); 39 | cipher->writeKey(volumeKey, keyBuf); 40 | 41 | CipherKey readKey = cipher->readKey(keyBuf, true); 42 | ASSERT_TRUE(readKey.valid()); 43 | ASSERT_TRUE(readKey == volumeKey); 44 | ASSERT_FALSE(readKey == masterKey); 45 | 46 | delete[] keyBuf; 47 | } 48 | } 49 | 50 | } // namespace 51 | -------------------------------------------------------------------------------- /cipher/openssl.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2007, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _openssl_incl_ 22 | #define _openssl_incl_ 23 | 24 | #include "base/Registry.h" 25 | 26 | namespace encfs { 27 | 28 | class OpenSSL { 29 | public: 30 | static void init(bool isThreaded); 31 | static void shutdown(bool isThreaded); 32 | 33 | static void registerCiphers(); 34 | }; 35 | 36 | } // namespace encfs 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /base/shared_ptr.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License as published by the 10 | * Free Software Foundation, either version 3 of the License, or (at your 11 | * option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 16 | * for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _SHARED_PTR_incl_ 23 | #define _SHARED_PTR_incl_ 24 | 25 | #include "base/config.h" 26 | 27 | #ifdef HAVE_TR1_MEMORY 28 | #include 29 | using std::tr1::shared_ptr; 30 | using std::tr1::dynamic_pointer_cast; 31 | #else 32 | #include 33 | using std::shared_ptr; 34 | using std::dynamic_pointer_cast; 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /base/i18n.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _i18n_incl_ 22 | #define _i18n_incl_ 23 | 24 | #if defined(LOCALEDIR) 25 | 26 | #include "base/gettext.h" 27 | // make shortcut for gettext 28 | #define _(STR) gettext(STR) 29 | 30 | #include "base/autosprintf.h" 31 | using gnu::autosprintf; 32 | 33 | #else 34 | 35 | #define gettext(STR) (STR) 36 | #define gettext_noop(STR) (STR) 37 | #define _(STR) (STR) 38 | #define N_(STR) (STR) 39 | 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /cipher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | link_directories (${Encfs_BINARY_DIR}/base) 2 | 3 | if (WITH_COMMON_CRYPTO) 4 | set (EXTRA_LIBS ${SECURITY_FRAMEWORK}) 5 | set (EXTRA_SOURCE CommonCrypto.cpp) 6 | elseif (WITH_OPENSSL) 7 | include_directories (${OPENSSL_INCLUDE_DIR}) 8 | set (EXTRA_LIBS ${OPENSSL_LIBRARIES}) 9 | set (EXTRA_SOURCE openssl.cpp) 10 | elseif (WITH_BOTAN) 11 | set (EXTRA_LIBS ${BOTAN_LIBRARIES}) 12 | set (EXTRA_SOURCE botan.cpp) 13 | include_directories (${BOTAN_INCLUDE_DIR}) 14 | endif (WITH_COMMON_CRYPTO) 15 | 16 | add_library (encfs-cipher 17 | BlockCipher.cpp 18 | CipherKey.cpp 19 | CipherV1.cpp 20 | MAC.cpp 21 | MemoryPool.cpp 22 | NullCiphers.cpp 23 | PBKDF.cpp 24 | readpassphrase.cpp 25 | StreamCipher.cpp 26 | ${EXTRA_SOURCE} 27 | ) 28 | 29 | target_link_libraries (encfs-cipher 30 | ${EXTRA_LIBS} 31 | ) 32 | 33 | if (GTEST_FOUND) 34 | link_directories (${PROJECT_BINARY_DIR}/base) 35 | include_directories (${GTEST_INCLUDE_DIR}) 36 | 37 | file (GLOB TEST_FILES "*_test.cpp") 38 | 39 | add_executable (cipher-tests 40 | testing.cpp 41 | ${TEST_FILES} 42 | ) 43 | 44 | target_link_libraries (cipher-tests 45 | ${GTEST_BOTH_LIBRARIES} 46 | encfs-cipher 47 | encfs-base 48 | ${GLOG_LIBRARIES} 49 | ) 50 | 51 | add_test (CipherTests cipher-tests) 52 | GTEST_ADD_TESTS (cipher-tests "${CipherTestArgs}" ${TEST_FILES}) 53 | endif (GTEST_FOUND) 54 | -------------------------------------------------------------------------------- /cipher/testing.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _CIPHER_TESTING_incl_ 23 | #define _CIPHER_TESTING_incl_ 24 | 25 | #include 26 | 27 | #include "base/types.h" 28 | 29 | namespace encfs { 30 | 31 | std::string stringToHex(const byte *data, int len); 32 | 33 | template 34 | std::string stringToHex(const T &value) { 35 | return stringToHex(value.data(), value.size()); 36 | } 37 | 38 | void setDataFromHex(byte *out, int size, const char *hex); 39 | 40 | } // namespace encfs 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /CMakeModules/FindGFlags.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find GFLAGS 2 | # 3 | # The following variables are optionally searched for defaults 4 | # GFLAGS_ROOT_DIR: Base directory where all GFLAGS components are found 5 | # 6 | # The following are set after configuration is done: 7 | # GFLAGS_FOUND 8 | # GFLAGS_INCLUDE_DIRS 9 | # GFLAGS_LIBRARIES 10 | # GFLAGS_LIBRARYRARY_DIRS 11 | 12 | include(FindPackageHandleStandardArgs) 13 | 14 | set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags") 15 | 16 | # We are testing only a couple of files in the include directories 17 | if(WIN32) 18 | find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h 19 | PATHS ${GFLAGS_ROOT_DIR}/src/windows) 20 | else() 21 | find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h 22 | PATHS ${GFLAGS_ROOT_DIR}) 23 | endif() 24 | 25 | if(MSVC) 26 | find_library(GFLAGS_LIBRARY_RELEASE 27 | NAMES libgflags 28 | PATHS ${GFLAGS_ROOT_DIR} 29 | PATH_SUFFIXES Release) 30 | 31 | find_library(GFLAGS_LIBRARY_DEBUG 32 | NAMES libgflags-debug 33 | PATHS ${GFLAGS_ROOT_DIR} 34 | PATH_SUFFIXES Debug) 35 | 36 | set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG}) 37 | else() 38 | find_library(GFLAGS_LIBRARY gflags) 39 | endif() 40 | 41 | find_package_handle_standard_args(GFLAGS DEFAULT_MSG 42 | GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY) 43 | 44 | 45 | if(GFLAGS_FOUND) 46 | set(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR}) 47 | set(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY}) 48 | endif() 49 | -------------------------------------------------------------------------------- /CMakeModules/FindBotan.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find the Botan library 2 | # 3 | # Once done this will define 4 | # 5 | # BOTAN_FOUND - System has Botan 6 | # BOTAN_INCLUDE_DIR - The Botan include directory 7 | # BOTAN_LIBRARIES - The libraries needed to use Botan 8 | # BOTAN_DEFINITIONS - Compiler switches required for using Botan 9 | 10 | IF (BOTAN_INCLUDE_DIR AND BOTAN_LIBRARY) 11 | # in cache already 12 | SET(Botan_FIND_QUIETLY TRUE) 13 | ENDIF (BOTAN_INCLUDE_DIR AND BOTAN_LIBRARY) 14 | 15 | IF (NOT WIN32) 16 | # try using pkg-config to get the directories and then use these values 17 | # in the FIND_PATH() and FIND_LIBRARY() calls 18 | # also fills in BOTAN_DEFINITIONS, although that isn't normally useful 19 | FIND_PACKAGE(PkgConfig) 20 | PKG_SEARCH_MODULE(PC_BOTAN botan-1.10 botan-1.9 botan-1.8 botan) 21 | SET(BOTAN_DEFINITIONS ${PC_BOTAN_CFLAGS}) 22 | ENDIF (NOT WIN32) 23 | 24 | FIND_PATH(BOTAN_INCLUDE_DIR botan/botan.h 25 | HINTS 26 | ${PC_BOTAN_INCLUDEDIR} 27 | ${PC_BOTAN_INCLUDE_DIRS} 28 | ) 29 | 30 | FIND_LIBRARY(BOTAN_LIBRARY NAMES ${PC_BOTAN_LIBRARIES} 31 | HINTS 32 | ${PC_BOTAN_LIBDIR} 33 | ${PC_BOTAN_LIBRARY_DIRS} 34 | ) 35 | 36 | MARK_AS_ADVANCED(BOTAN_INCLUDE_DIR BOTAN_LIBRARY) 37 | 38 | # handle the QUIETLY and REQUIRED arguments and set BOTAN_FOUND to TRUE if 39 | # all listed variables are TRUE 40 | INCLUDE(FindPackageHandleStandardArgs) 41 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Botan DEFAULT_MSG BOTAN_LIBRARY BOTAN_INCLUDE_DIR) 42 | 43 | IF(BOTAN_FOUND) 44 | SET(BOTAN_LIBRARIES ${BOTAN_LIBRARY}) 45 | SET(BOTAN_INCLUDE_DIRS ${BOTAN_INCLUDE_DIR}) 46 | ENDIF() 47 | -------------------------------------------------------------------------------- /fs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | protobuf_generate_cpp (PROTO_SRCS PROTO_HDRS ${PROJECT_SOURCE_DIR}/protos/fsconfig.proto) 2 | 3 | include_directories (${PROJECT_BINARY_DIR}/base) 4 | add_library (encfs-fs 5 | encfs.cpp 6 | Context.cpp 7 | FileIO.cpp 8 | RawFileIO.cpp 9 | BlockFileIO.cpp 10 | CipherFileIO.cpp 11 | MACFileIO.cpp 12 | NameIO.cpp 13 | StreamNameIO.cpp 14 | BlockNameIO.cpp 15 | NullNameIO.cpp 16 | DirNode.cpp 17 | FileNode.cpp 18 | FileUtils.cpp 19 | ${PROTO_SRCS} 20 | ${PROTO_HDRS} 21 | ) 22 | 23 | target_link_libraries (encfs-fs 24 | ${PROTOBUF_LIBRARY} 25 | ${CMAKE_THREAD_LIBS_INIT} 26 | ) 27 | 28 | add_executable (checkops 29 | checkops.cpp 30 | ) 31 | target_link_libraries (checkops 32 | encfs-fs 33 | encfs-cipher 34 | encfs-base 35 | ${GLOG_LIBRARIES} 36 | ) 37 | 38 | # Unit tests are optional, depends on libgtest (Google's C++ test framework). 39 | if (GTEST_FOUND) 40 | link_directories (${PROJECT_BINARY_DIR}/base) 41 | link_directories (${PROJECT_BINARY_DIR}/cipher) 42 | 43 | include_directories (${GTEST_INCLUDE_DIR}) 44 | 45 | file (GLOB TEST_FILES "*_test.cpp") 46 | 47 | add_executable (fs-tests 48 | MemBlockFileIO.cpp 49 | MemFileIO.cpp 50 | testing.cpp 51 | ${TEST_FILES} 52 | ) 53 | 54 | target_link_libraries (fs-tests 55 | ${GTEST_BOTH_LIBRARIES} 56 | encfs-fs 57 | encfs-cipher 58 | encfs-base 59 | ${GLOG_LIBRARIES} 60 | ) 61 | 62 | add_test (FSTests fs-tests) 63 | GTEST_ADD_TESTS (fs-tests "${FSTestArgs}" ${TEST_FILES}) 64 | endif (GTEST_FOUND) 65 | -------------------------------------------------------------------------------- /util/encfssh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script mounts an encfs filesystem, starts a shell in the mounted 4 | # directory, and then unmounts the filesystem when the shell exits. 5 | # This is an equivalent of the cfssh utility for cfs. 6 | # Contributed by David Rosenstrauch. 7 | 8 | canonicalize() { 9 | cd "$1" 10 | pwd 11 | } 12 | 13 | 14 | if [ -z "$1" -o "$1" = "-h" ]; then 15 | echo Usage: encfssh encrypted_directory [unencrypted-directory [-p]] 16 | echo " -p mount the unencrypted directory as public" 17 | exit 1 18 | fi 19 | 20 | enc_dir=$1 21 | unenc_dir_given=false 22 | mount_public=false 23 | if [ ! -z "$2" ]; then 24 | unenc_dir_given=true 25 | unenc_dir=$2 26 | for arg in "$@" ; do 27 | if [ "$arg" = "-p" ]; then 28 | mount_public=true 29 | fi 30 | done 31 | else 32 | unenc_dir=.$RANDOM.$RANDOM 33 | fi 34 | 35 | if [ ! -d "$enc_dir" ]; then 36 | mkdir $enc_dir 37 | fi 38 | if [ ! -d "$unenc_dir" ]; then 39 | mkdir $unenc_dir 40 | fi 41 | 42 | enc_dir=$(canonicalize "$enc_dir") 43 | unenc_dir=$(canonicalize "$unenc_dir") 44 | 45 | options="" 46 | if $unenc_dir_given; then 47 | if $mount_public; then 48 | options="-- -o allow_other" 49 | fi 50 | fi 51 | 52 | # Attach the directory and change into it 53 | if encfs $enc_dir $unenc_dir $options; then :; else 54 | echo "encfs failed" 55 | rmdir $unenc_dir 56 | exit 1 57 | fi 58 | if ! $unenc_dir_given; then 59 | chmod 700 $unenc_dir 60 | fi 61 | echo "Directory is $unenc_dir" 62 | orig_dir=$(pwd) 63 | cd $unenc_dir 64 | 65 | # Set the shell up 66 | exec /bin/sh -c "$SHELL ; cd $orig_dir ; fusermount -u $unenc_dir ; if ! $unenc_dir_given; then rmdir $unenc_dir; fi" 67 | 68 | -------------------------------------------------------------------------------- /cipher/testing.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #include "base/config.h" 6 | #include "cipher/testing.h" 7 | 8 | #ifdef HAVE_VALGRIND_MEMCHECK_H 9 | #include 10 | #endif 11 | 12 | namespace encfs { 13 | 14 | static const char hexLut[] = "0123456789abcdef"; 15 | 16 | std::string stringToHex(const byte *data, int len) { 17 | std::string out; 18 | out.reserve(2 * len); 19 | for (int i = 0; i < len; ++i) { 20 | unsigned int c = (unsigned int)data[i] & 0xff; 21 | int first = (unsigned int)c >> 4; 22 | int second = (unsigned int)c & 15; 23 | 24 | out.push_back(hexLut[first]); 25 | out.push_back(hexLut[second]); 26 | } 27 | return out; 28 | } 29 | 30 | void setDataFromHex(byte *out, int len, const char *hex) { 31 | #ifdef HAVE_VALGRIND_MEMCHECK_H 32 | VALGRIND_CHECK_MEM_IS_ADDRESSABLE(out, len); 33 | #endif 34 | bool odd = false; 35 | unsigned int last = 0; 36 | while (len > 0 && *hex != '\0') { 37 | byte nibble = *hex++; 38 | if (nibble >= '0' && nibble <= '9') 39 | nibble -= '0'; 40 | else if (nibble >= 'A' && nibble <= 'F') 41 | nibble -= 'A' - 10; 42 | else if (nibble >= 'a' && nibble <= 'f') 43 | nibble -= 'a' - 10; 44 | else 45 | nibble = 0; 46 | 47 | last |= (unsigned int)nibble; 48 | if (odd) { 49 | *out++ = (byte)last; 50 | --len; 51 | last = 0; 52 | odd = false; 53 | } else { 54 | last <<= 4; 55 | odd = true; 56 | } 57 | } 58 | } 59 | 60 | int main(int argc, char **argv) { 61 | google::InitGoogleLogging(argv[0]); 62 | ::testing::InitGoogleTest(&argc, argv); 63 | return RUN_ALL_TESTS(); 64 | } 65 | 66 | } // namespace encfs 67 | -------------------------------------------------------------------------------- /fs/testextpass: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -w 2 | 3 | # Sample password prompt program. Demonstration of how to interface with 4 | # encfs's --extpass option. Note that encfs's extpass interface was chosen to 5 | # work with existing password prompt programs, like ssh-askpass. 6 | # 7 | # The external password program is expected to somehow prompt for the password 8 | # and return the password on stdout. Encfs also provides some extra 9 | # information which is stored in environment variables. 10 | # 11 | # Quick Start: The only necessary part of this script for encfs operation is 12 | # the final part which prints the password to stdout. 13 | # 14 | # Encfs records some environment variables with useful information: 15 | # "encfs_root" holds a path to the raw encrypted data. 16 | # "encfs_stdout" holds a file descriptor number which will display data to 17 | # standard output (because standard output is used for the password). 18 | # "encfs_stderr" holds a file descriptor number which for standard error.. 19 | 20 | use strict; 21 | use IO::Handle; 22 | 23 | # find out where we can send data to display to the user (assuming encfs was 24 | # started in a terminal!) 25 | my $realOut = $ENV{"encfs_stdout"} || fileno(STDOUT); 26 | #my $realErr = $ENV{"encfs_stderr"} || fileno(STDERR); 27 | #my $rootDir = $ENV{"encfs_root"} || "[unknown]"; 28 | #system("xmessage realOut=$realOut, err=$realErr"); 29 | 30 | # for grins, show all encfs related environment variables to encfs's standard 31 | # output 32 | my $io = new IO::Handle; 33 | if($io->fdopen($realOut, "w")) 34 | { 35 | while (my ($key,$value) = each %ENV) 36 | { 37 | $io->print("$key=$value\n") if($key=~/encfs/); 38 | } 39 | } 40 | $io->close(); 41 | 42 | ## XXX XXX - This is the only part necessary for encfs to be happy. 43 | # the functional part -- print the encfs password to stdout 44 | print "test\n"; 45 | 46 | -------------------------------------------------------------------------------- /base/Interface.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _Interface_incl_ 22 | #define _Interface_incl_ 23 | 24 | #include 25 | #include "base/interface.pb.h" 26 | 27 | namespace encfs { 28 | 29 | // check if A implements the interface described by B. 30 | // Note that implements(A, B) is not the same as implements(B, A) 31 | // This checks the current() version and age() against B.current() for 32 | // compatibility. Even if A.implements(B) is true, B > A may also be 33 | // true, meaning B is a newer revision of the interface then A. 34 | bool implements(const Interface &a, const Interface &b); 35 | Interface makeInterface(const std::string &name, int major, int minor, int age); 36 | 37 | // Read operation 38 | class ConfigVar; 39 | const ConfigVar &operator>>(const ConfigVar &, Interface &); 40 | 41 | bool operator!=(const Interface &a, const Interface &b); 42 | 43 | } // namespace encfs 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /cipher/CipherKey.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2007, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _CipherKey_incl_ 22 | #define _CipherKey_incl_ 23 | 24 | #include 25 | 26 | #include "base/shared_ptr.h" 27 | #include "base/types.h" 28 | 29 | namespace encfs { 30 | 31 | class SecureMem; 32 | 33 | class CipherKey { 34 | public: 35 | CipherKey(); // Creates a key for which valid() returns false. 36 | explicit CipherKey(int length); 37 | CipherKey(const byte *data, int length); 38 | CipherKey(const CipherKey &src); 39 | ~CipherKey(); 40 | 41 | CipherKey &operator=(const CipherKey &src); 42 | 43 | byte *data() const; 44 | int size() const; 45 | 46 | // Clear memory associated with key. 47 | void reset(); 48 | 49 | bool valid() const; 50 | 51 | private: 52 | bool _valid; 53 | shared_ptr _mem; 54 | }; 55 | 56 | bool operator==(const CipherKey &a, const CipherKey &b); 57 | 58 | } // namespace encfs 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /fs/MemFileIO.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _MEMFILEIO_incl_ 23 | #define _MEMFILEIO_incl_ 24 | 25 | #include "fs/FileIO.h" 26 | 27 | #include 28 | #include 29 | 30 | namespace encfs { 31 | 32 | class MemFileIO : public FileIO { 33 | public: 34 | MemFileIO(int size); 35 | virtual ~MemFileIO(); 36 | 37 | virtual Interface interface() const; 38 | 39 | virtual void setFileName(const char *name); 40 | virtual const char *getFileName() const; 41 | 42 | virtual int open(int flags); 43 | 44 | virtual int getAttr(struct stat *stbuf) const; 45 | virtual off_t getSize() const; 46 | 47 | virtual ssize_t read(const IORequest &req) const; 48 | virtual bool write(const IORequest &req); 49 | 50 | virtual int truncate(off_t size); 51 | virtual bool isWritable() const; 52 | 53 | private: 54 | std::vector buf; 55 | std::string name; 56 | bool writable; 57 | }; 58 | 59 | } // namespace encfs 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /util/makeKey.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2008, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 | * more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along with 18 | * this program. If not, see . 19 | */ 20 | 21 | #include "encfs.h" 22 | 23 | #include "Cipher.h" 24 | #include "CipherKey.h" 25 | #include "openssl.h" 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | 32 | void genKey(const shared_ptr &cipher) { 33 | CipherKey key = cipher->newRandomKey(); 34 | 35 | // encode with itself 36 | string b64Key = cipher->encodeAsString(key, key); 37 | 38 | cout << b64Key << "\n"; 39 | } 40 | 41 | int main(int argc, char **argv) { 42 | pid_t pid = getpid(); 43 | cerr << "pid = " << pid << "\n"; 44 | 45 | if (argc != 3) { 46 | cerr << "usage: makeKey [AES|Blowfish] [128|160|192|224|256]\n"; 47 | return 1; 48 | } 49 | 50 | const char *type = argv[1]; 51 | int size = atoi(argv[2]); 52 | 53 | openssl_init(false); 54 | 55 | // get a list of the available algorithms 56 | shared_ptr cipher = Cipher::New(type, size); 57 | genKey(cipher); 58 | 59 | // openssl_shutdown(false); 60 | } 61 | -------------------------------------------------------------------------------- /fs/NullNameIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _NullNameIO_incl_ 22 | #define _NullNameIO_incl_ 23 | 24 | #include "fs/NameIO.h" 25 | 26 | namespace encfs { 27 | 28 | class NullNameIO : public NameIO { 29 | public: 30 | static Interface CurrentInterface(); 31 | 32 | NullNameIO(); 33 | 34 | virtual ~NullNameIO(); 35 | 36 | virtual Interface interface() const override; 37 | 38 | virtual int maxEncodedNameLen(int plaintextNameLen) const override; 39 | virtual int maxDecodedNameLen(int encodedNameLen) const override; 40 | 41 | // hack to help with static builds 42 | static bool Enabled(); 43 | 44 | protected: 45 | virtual std::string encodeName(const std::string &plaintextName, 46 | uint64_t *iv) const override; 47 | virtual std::string decodeName(const std::string &encodedName, 48 | uint64_t *iv) const override; 49 | 50 | private: 51 | }; 52 | 53 | } // namespace encfs 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /fs/NameIO_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "cipher/CipherV1.h" 5 | 6 | #include "fs/BlockNameIO.h" 7 | #include "fs/NameIO.h" 8 | #include "fs/NullNameIO.h" 9 | #include "fs/StreamNameIO.h" 10 | #include "fs/testing.h" 11 | 12 | namespace { 13 | 14 | using namespace encfs; 15 | using std::string; 16 | 17 | string TEST_PATHS[] = {"a/b/c/d/e", // 18 | "/a/b", // 19 | "/a", // 20 | "/", // 21 | "../../foo/bar", // 22 | "./.encfs", // 23 | "."}; 24 | 25 | TEST(NameIOTest, NameIO) { 26 | NameIO::AlgorithmList algorithms = NameIO::GetAlgorithmList(true); 27 | // Test all NameIO algorithms. 28 | for (auto algorithm : algorithms) { 29 | shared_ptr cipher = CipherV1::New("AES", 256); 30 | CipherKey key = cipher->newRandomKey(); 31 | cipher->setKey(key); 32 | 33 | // Test all supported versions. 34 | for (unsigned int version = algorithm.iface.major() - algorithm.iface.age(); 35 | version <= algorithm.iface.major(); ++version) { 36 | Interface iface = makeInterface(algorithm.iface.name(), version, 0, 0); 37 | SCOPED_TRACE(testing::Message() << "Testing " << iface.DebugString()); 38 | 39 | auto io = NameIO::New(iface, cipher); 40 | 41 | // Check round-trip of test paths. 42 | for (string path : TEST_PATHS) { 43 | string encoded = io->encodePath(path); 44 | string decoded = io->decodePath(encoded); 45 | ASSERT_EQ(path, decoded); 46 | } 47 | 48 | // Try encoding names of various lengths. 49 | for (int len = 1; len < 40; ++len) { 50 | string name(len, 'A'); 51 | string encoded = io->encodeName(name); 52 | string decoded = io->decodeName(encoded); 53 | ASSERT_EQ(name, decoded); 54 | } 55 | } 56 | } 57 | } 58 | 59 | } // namespace 60 | -------------------------------------------------------------------------------- /base/ConfigReader.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _ConfigReader_incl_ 22 | #define _ConfigReader_incl_ 23 | 24 | #include 25 | #include 26 | 27 | #include "base/ConfigVar.h" 28 | 29 | namespace encfs { 30 | 31 | /* 32 | handles Configuration load / store for Encfs filesystems. 33 | 34 | loading existing config file example: 35 | 36 | ConfigReader cfg; 37 | cfg.load( filesystemConfigFile ); 38 | 39 | Interface iface; 40 | cfg["cipher"] >> iface; 41 | 42 | 43 | creating new config example: 44 | 45 | ConfigReader cfg; 46 | cfg["cipher"] << cipher->interface(); 47 | */ 48 | class ConfigReader { 49 | public: 50 | ConfigReader(); 51 | ~ConfigReader(); 52 | 53 | bool load(const char *fileName); 54 | 55 | bool loadFromVar(ConfigVar &var); 56 | 57 | ConfigVar operator[](const std::string &varName) const; 58 | ConfigVar &operator[](const std::string &varName); 59 | 60 | private: 61 | std::map vars; 62 | }; 63 | 64 | } // namespace encfs 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /fs/MemBlockFileIO.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _MEMBLOCKFILEIO_incl_ 23 | #define _MEMBLOCKFILEIO_incl_ 24 | 25 | #include "fs/BlockFileIO.h" 26 | 27 | #include 28 | #include 29 | 30 | namespace encfs { 31 | 32 | class MemFileIO; 33 | 34 | class MemBlockFileIO : public BlockFileIO { 35 | public: 36 | MemBlockFileIO(int blockSize, const FSConfigPtr &cfg); 37 | virtual ~MemBlockFileIO(); 38 | 39 | virtual Interface interface() const; 40 | 41 | virtual void setFileName(const char *name); 42 | virtual const char *getFileName() const; 43 | 44 | virtual int open(int flags); 45 | 46 | virtual int getAttr(struct stat *stbuf) const; 47 | virtual off_t getSize() const; 48 | 49 | virtual bool isWritable() const; 50 | 51 | virtual int truncate(off_t size); 52 | 53 | protected: 54 | virtual ssize_t readOneBlock(const IORequest &req) const; 55 | virtual bool writeOneBlock(const IORequest &req); 56 | 57 | private: 58 | MemFileIO *impl; 59 | }; 60 | 61 | } // namespace encfs 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /po/Makevars: -------------------------------------------------------------------------------- 1 | # Makefile variables for PO directory in any package using GNU gettext. 2 | 3 | # Usually the message domain is the same as the package name. 4 | DOMAIN = $(PACKAGE) 5 | 6 | # These two variables depend on the location of this directory. 7 | subdir = po 8 | top_builddir = .. 9 | 10 | # These options get passed to xgettext. 11 | XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ 12 | 13 | # This is the copyright holder that gets inserted into the header of the 14 | # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding 15 | # package. (Note that the msgstr strings, extracted from the package's 16 | # sources, belong to the copyright holder of the package.) Translators are 17 | # expected to transfer the copyright for their translations to this person 18 | # or entity, or to disclaim their copyright. The empty string stands for 19 | # the public domain; in this case the translators are expected to disclaim 20 | # their copyright. 21 | COPYRIGHT_HOLDER = Valient Gough 22 | 23 | # This is the email address or URL to which the translators shall report 24 | # bugs in the untranslated strings: 25 | # - Strings which are not entire sentences, see the maintainer guidelines 26 | # in the GNU gettext documentation, section 'Preparing Strings'. 27 | # - Strings which use unclear terms or require additional context to be 28 | # understood. 29 | # - Strings which make invalid assumptions about notation of date, time or 30 | # money. 31 | # - Pluralisation problems. 32 | # - Incorrect English spelling. 33 | # - Incorrect formatting. 34 | # It can be your email address, or a mailing list address where translators 35 | # can write to without being subscribed, or the URL of a web page through 36 | # which the translators can contact you. 37 | MSGID_BUGS_ADDRESS = https://translations.launchpad.net/encfs/main/+pots/encfs 38 | 39 | # This is the list of locale categories, beyond LC_MESSAGES, for which the 40 | # message catalogs shall be used. It is usually empty. 41 | EXTRA_LOCALE_CATEGORIES = 42 | -------------------------------------------------------------------------------- /fs/RawFileIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _RawFileIO_incl_ 22 | #define _RawFileIO_incl_ 23 | 24 | #include "fs/FileIO.h" 25 | 26 | #include 27 | 28 | namespace encfs { 29 | 30 | class RawFileIO : public FileIO { 31 | public: 32 | RawFileIO(); 33 | RawFileIO(const std::string &fileName); 34 | virtual ~RawFileIO(); 35 | 36 | virtual Interface interface() const; 37 | 38 | virtual void setFileName(const char *fileName); 39 | virtual const char *getFileName() const; 40 | 41 | virtual int open(int flags); 42 | 43 | virtual int getAttr(struct stat *stbuf) const; 44 | virtual off_t getSize() const; 45 | 46 | virtual ssize_t read(const IORequest &req) const; 47 | virtual bool write(const IORequest &req); 48 | 49 | virtual int truncate(off_t size); 50 | 51 | virtual bool isWritable() const; 52 | 53 | protected: 54 | std::string name; 55 | 56 | mutable bool knownSize; 57 | mutable off_t fileSize; 58 | 59 | int fd; 60 | int oldfd; 61 | bool canWrite; 62 | }; 63 | 64 | } // namespace encfs 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /fs/StreamNameIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _StreamNameIO_incl_ 22 | #define _StreamNameIO_incl_ 23 | 24 | #include "fs/NameIO.h" 25 | 26 | namespace encfs { 27 | 28 | class CipherV1; 29 | 30 | class StreamNameIO : public NameIO { 31 | public: 32 | static Interface CurrentInterface(); 33 | 34 | StreamNameIO(const Interface &iface, const shared_ptr &cipher); 35 | virtual ~StreamNameIO(); 36 | 37 | virtual Interface interface() const override; 38 | 39 | virtual int maxEncodedNameLen(int plaintextNameLen) const override; 40 | virtual int maxDecodedNameLen(int encodedNameLen) const override; 41 | 42 | // hack to help with static builds 43 | static bool Enabled(); 44 | 45 | protected: 46 | virtual std::string encodeName(const std::string &plaintextName, 47 | uint64_t *iv) const override; 48 | virtual std::string decodeName(const std::string &encodedName, 49 | uint64_t *iv) const override; 50 | 51 | private: 52 | int _interface; 53 | shared_ptr _cipher; 54 | }; 55 | 56 | } // namespace encfs 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /fs/BlockFileIO_test.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2012 Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License as published by the Free 9 | * Software Foundation, either version 3 of the License, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | * details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "cipher/MemoryPool.h" 26 | 27 | #include "fs/testing.h" 28 | #include "fs/FileUtils.h" 29 | #include "fs/FSConfig.h" 30 | #include "fs/MemFileIO.h" 31 | #include "fs/MemBlockFileIO.h" 32 | 33 | using namespace encfs; 34 | 35 | namespace { 36 | 37 | TEST(BlockFileIOTest, BasicIO) { 38 | // Base for comparison. 39 | MemFileIO base(1024); 40 | ASSERT_EQ(1024, base.getSize()); 41 | 42 | FSConfigPtr cfg = makeConfig(CipherV1::New("Null"), 512); 43 | MemBlockFileIO block(512, cfg); 44 | block.truncate(1024); 45 | ASSERT_EQ(1024, block.getSize()); 46 | 47 | MemBlock mb; 48 | mb.allocate(256); 49 | 50 | IORequest req; 51 | req.offset = 0; 52 | req.data = mb.data; 53 | req.dataLen = 256; 54 | 55 | for (int i = 0; i < 4; i++) { 56 | req.offset = i * 256; 57 | memset(req.data, 0, req.dataLen); 58 | ASSERT_TRUE(base.write(req)); 59 | 60 | req.offset = i * 256; 61 | memset(req.data, 0, req.dataLen); 62 | ASSERT_TRUE(block.write(req)); 63 | } 64 | 65 | ASSERT_NO_FATAL_FAILURE(compare(&base, &block, 0, 1024)); 66 | } 67 | 68 | } // namespace encfs 69 | -------------------------------------------------------------------------------- /cipher/NullCiphers.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "cipher/NullCiphers.h" 23 | 24 | #include "cipher/BlockCipher.h" 25 | #include "cipher/StreamCipher.h" 26 | 27 | namespace encfs { 28 | 29 | class NullCipher : public BlockCipher { 30 | public: 31 | virtual ~NullCipher() {} 32 | 33 | virtual int blockSize() const { return 8; } 34 | 35 | virtual bool setKey(const CipherKey &key) { return true; } 36 | 37 | virtual bool encrypt(const byte *iv, const byte *in, byte *out, 38 | int numBytes) { 39 | if (in != out) memcpy(out, in, numBytes); 40 | return true; 41 | } 42 | 43 | virtual bool decrypt(const byte *iv, const byte *in, byte *out, 44 | int numBytes) { 45 | if (in != out) memcpy(out, in, numBytes); 46 | return true; 47 | } 48 | 49 | static Properties GetProperties() { 50 | Properties props; 51 | props.keySize = Range(0); 52 | props.cipher = "NullCipher"; 53 | props.mode = "ECB"; 54 | props.library = "internal"; 55 | return props; 56 | } 57 | }; 58 | 59 | REGISTER_CLASS(NullCipher, BlockCipher); 60 | REGISTER_CLASS(NullCipher, StreamCipher); 61 | 62 | void NullCiphers::registerCiphers() { 63 | // Nothing required. 64 | } 65 | 66 | } // namespace encfs 67 | -------------------------------------------------------------------------------- /fs/MACFileIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _MACFileIO_incl_ 22 | #define _MACFileIO_incl_ 23 | 24 | #include "cipher/CipherV1.h" 25 | #include "fs/BlockFileIO.h" 26 | 27 | namespace encfs { 28 | 29 | class MACFileIO : public BlockFileIO { 30 | public: 31 | /* 32 | If warnOnlyMode is enabled, then a MAC comparison failure will only 33 | result in a warning message from encfs -- the garbled data will still 34 | be made available.. 35 | */ 36 | MACFileIO(const shared_ptr &base, const FSConfigPtr &cfg); 37 | MACFileIO(); 38 | virtual ~MACFileIO(); 39 | 40 | virtual Interface interface() const; 41 | 42 | virtual void setFileName(const char *fileName); 43 | virtual const char *getFileName() const; 44 | virtual bool setIV(uint64_t iv); 45 | 46 | virtual int open(int flags); 47 | virtual int getAttr(struct stat *stbuf) const; 48 | virtual off_t getSize() const; 49 | 50 | virtual int truncate(off_t size); 51 | 52 | virtual bool isWritable() const; 53 | 54 | private: 55 | virtual ssize_t readOneBlock(const IORequest &req) const; 56 | virtual bool writeOneBlock(const IORequest &req); 57 | 58 | shared_ptr base; 59 | shared_ptr cipher; 60 | int macBytes; 61 | int randBytes; 62 | bool warnOnly; 63 | }; 64 | 65 | } // namespace encfs 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /cipher/CipherKey.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "cipher/CipherKey.h" 23 | 24 | #include "base/shared_ptr.h" 25 | #include "base/types.h" 26 | #include "cipher/MemoryPool.h" 27 | 28 | namespace encfs { 29 | 30 | CipherKey::CipherKey() : _valid(false) {} 31 | 32 | CipherKey::CipherKey(int length) : _valid(true) { 33 | if (length > 0) _mem.reset(new SecureMem(length)); 34 | } 35 | 36 | CipherKey::CipherKey(const byte *data, int length) : _valid(true) { 37 | _mem.reset(new SecureMem(length)); 38 | memcpy(_mem->data(), data, length); 39 | } 40 | 41 | CipherKey::CipherKey(const CipherKey &src) 42 | : _valid(src._valid), _mem(src._mem) {} 43 | 44 | CipherKey::~CipherKey() {} 45 | 46 | CipherKey &CipherKey::operator=(const CipherKey &src) { 47 | _mem = src._mem; 48 | _valid = src._valid; 49 | return *this; 50 | } 51 | 52 | byte *CipherKey::data() const { return !_mem ? NULL : _mem->data(); } 53 | 54 | int CipherKey::size() const { return !_mem ? 0 : _mem->size(); } 55 | 56 | void CipherKey::reset() { 57 | _mem.reset(); 58 | _valid = false; 59 | } 60 | 61 | bool CipherKey::valid() const { return _valid; } 62 | 63 | bool operator==(const CipherKey &a, const CipherKey &b) { 64 | if (a.size() != b.size()) return false; 65 | return memcmp(a.data(), b.data(), a.size()) == 0; 66 | } 67 | 68 | } // namespace encfs 69 | -------------------------------------------------------------------------------- /cipher/StreamCipher.h: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #ifndef _STREAMCIPHER_incl_ 23 | #define _STREAMCIPHER_incl_ 24 | 25 | #include "base/Range.h" 26 | #include "base/Registry.h" 27 | #include "base/shared_ptr.h" 28 | #include "base/types.h" 29 | #include "cipher/CipherKey.h" 30 | 31 | namespace encfs { 32 | 33 | static const char NAME_AES_CFB[] = "AES/CFB"; 34 | static const char NAME_BLOWFISH_CFB[] = "Blowfish/CFB"; 35 | 36 | class StreamCipher { 37 | public: 38 | DECLARE_REGISTERABLE_TYPE(StreamCipher); 39 | 40 | struct Properties { 41 | Range keySize; 42 | std::string cipher; 43 | std::string mode; 44 | std::string library; 45 | std::string toString() const { return cipher + "/" + mode; } 46 | Properties() {} 47 | Properties(Range keys, const char *cipher_, const char *mode_, 48 | const char *library_) 49 | : keySize(keys), cipher(cipher_), mode(mode_), library(library_) {} 50 | }; 51 | 52 | StreamCipher(); 53 | virtual ~StreamCipher(); 54 | 55 | virtual bool setKey(const CipherKey &key) = 0; 56 | 57 | virtual bool encrypt(const byte *ivec, const byte *in, byte *out, 58 | int numBytes) = 0; 59 | virtual bool decrypt(const byte *ivec, const byte *in, byte *out, 60 | int numBytes) = 0; 61 | }; 62 | 63 | } // namespace encfs 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /fs/NullNameIO.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "base/base64.h" 22 | #include "cipher/CipherV1.h" 23 | #include "fs/NullNameIO.h" 24 | 25 | #include 26 | #include 27 | 28 | namespace encfs { 29 | 30 | using std::string; 31 | 32 | static shared_ptr NewNNIO(const Interface &, 33 | const shared_ptr &) { 34 | return shared_ptr(new NullNameIO()); 35 | } 36 | 37 | static Interface NNIOIface = makeInterface("nameio/null", 1, 0, 0); 38 | static bool NullNameIO_registered = NameIO::Register( 39 | "Null", "No encryption of filenames", NNIOIface, NewNNIO, false); 40 | 41 | NullNameIO::NullNameIO() {} 42 | 43 | NullNameIO::~NullNameIO() {} 44 | 45 | Interface NullNameIO::interface() const { return NNIOIface; } 46 | 47 | Interface NullNameIO::CurrentInterface() { return NNIOIface; } 48 | 49 | int NullNameIO::maxEncodedNameLen(int plaintextNameLen) const { 50 | return plaintextNameLen; 51 | } 52 | 53 | int NullNameIO::maxDecodedNameLen(int encodedNameLen) const { 54 | return encodedNameLen; 55 | } 56 | 57 | string NullNameIO::encodeName(const string &plaintextName, uint64_t *iv) const { 58 | return plaintextName; 59 | } 60 | 61 | string NullNameIO::decodeName(const string &encodedName, uint64_t *iv) const { 62 | return encodedName; 63 | } 64 | 65 | bool NullNameIO::Enabled() { return true; } 66 | 67 | } // namespace encfs 68 | -------------------------------------------------------------------------------- /cipher/MemoryPool.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2003, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _MemoryPool_incl_ 22 | #define _MemoryPool_incl_ 23 | 24 | #include "base/config.h" 25 | #include "base/types.h" 26 | 27 | #ifdef WITH_BOTAN 28 | namespace Botan { 29 | template 30 | class SecureVector; 31 | } 32 | #endif 33 | 34 | namespace encfs { 35 | 36 | /* 37 | Memory Pool for fixed sized objects. 38 | Use SecureMem if storing sensitive information. 39 | 40 | Usage: 41 | MemBlock mb; 42 | mb.allocate( size ); 43 | // do things with storage in mb.data 44 | byte *buffer = mb.data; 45 | 46 | // memblock freed when destructed 47 | */ 48 | struct MemBlock { 49 | byte *data; 50 | int size; 51 | 52 | MemBlock(); 53 | ~MemBlock(); 54 | 55 | void allocate(int size); 56 | }; 57 | 58 | inline MemBlock::MemBlock() : data(0), size(0) {} 59 | 60 | class SecureMem { 61 | public: 62 | byte *data() const; 63 | int size() const; 64 | 65 | explicit SecureMem(int len); 66 | ~SecureMem(); 67 | 68 | private: 69 | #ifdef WITH_BOTAN 70 | Botan::SecureVector *data_; 71 | #else 72 | byte *data_; 73 | int size_; 74 | #endif 75 | }; 76 | 77 | #ifndef WITH_BOTAN 78 | inline byte *SecureMem::data() const { return data_; } 79 | inline int SecureMem::size() const { return size_; } 80 | #endif 81 | 82 | bool operator==(const SecureMem &a, const SecureMem &b); 83 | 84 | } // namespace encfs 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /fs/MemBlockFileIO.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "fs/MemBlockFileIO.h" 23 | #include "fs/MemFileIO.h" 24 | 25 | #include 26 | 27 | namespace encfs { 28 | 29 | static Interface MemBlockFileIO_iface = 30 | makeInterface("FileIO/MemBlock", 1, 0, 0); 31 | 32 | MemBlockFileIO::MemBlockFileIO(int blockSize, const FSConfigPtr& cfg) 33 | : BlockFileIO(blockSize, cfg), impl(new MemFileIO(0)) {} 34 | 35 | MemBlockFileIO::~MemBlockFileIO() {} 36 | 37 | Interface MemBlockFileIO::interface() const { return MemBlockFileIO_iface; } 38 | 39 | void MemBlockFileIO::setFileName(const char* name) { 40 | return impl->setFileName(name); 41 | } 42 | 43 | const char* MemBlockFileIO::getFileName() const { return impl->getFileName(); } 44 | 45 | int MemBlockFileIO::open(int flags) { return impl->open(flags); } 46 | 47 | int MemBlockFileIO::getAttr(struct stat* stbuf) const { 48 | return impl->getAttr(stbuf); 49 | } 50 | 51 | off_t MemBlockFileIO::getSize() const { return impl->getSize(); } 52 | 53 | ssize_t MemBlockFileIO::readOneBlock(const IORequest& req) const { 54 | return impl->read(req); 55 | } 56 | 57 | bool MemBlockFileIO::writeOneBlock(const IORequest& req) { 58 | return impl->write(req); 59 | } 60 | 61 | int MemBlockFileIO::truncate(off_t size) { return impl->truncate(size); } 62 | 63 | bool MemBlockFileIO::isWritable() const { return impl->isWritable(); } 64 | 65 | } // namespace encfs 66 | -------------------------------------------------------------------------------- /base/XmlReader.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2012, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _XmlReader_incl_ 22 | #define _XmlReader_incl_ 23 | 24 | #include 25 | #include "base/shared_ptr.h" 26 | #include "base/types.h" 27 | 28 | namespace encfs { 29 | 30 | class XmlValue; 31 | typedef shared_ptr XmlValuePtr; 32 | 33 | class Interface; 34 | 35 | class XmlValue { 36 | std::string value; 37 | 38 | public: 39 | XmlValue() {} 40 | 41 | XmlValue(const std::string &value) { this->value = value; } 42 | virtual ~XmlValue(); 43 | 44 | XmlValuePtr operator[](const char *path) const; 45 | 46 | const std::string &text() const { return value; } 47 | 48 | bool read(const char *path, std::string *out) const; 49 | bool readB64(const char *path, byte *out, int length) const; 50 | 51 | bool read(const char *path, int *out) const; 52 | bool read(const char *path, long *out) const; 53 | bool read(const char *path, double *out) const; 54 | bool read(const char *path, bool *out) const; 55 | 56 | bool read(const char *path, Interface *out) const; 57 | 58 | protected: 59 | virtual XmlValuePtr find(const char *name) const; 60 | }; 61 | 62 | class XmlReader { 63 | public: 64 | XmlReader(); 65 | ~XmlReader(); 66 | 67 | bool load(const char *fileName); 68 | 69 | XmlValuePtr operator[](const char *name) const; 70 | 71 | private: 72 | struct XmlReaderData; 73 | shared_ptr pd; 74 | }; 75 | 76 | } // namespace encfs 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /base/Mutex.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2003, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _Mutex_incl_ 22 | #define _Mutex_incl_ 23 | 24 | #include "base/config.h" 25 | 26 | #ifdef CMAKE_USE_PTHREADS_INIT 27 | #include 28 | #else 29 | #warning No thread support. 30 | #endif 31 | 32 | namespace encfs { 33 | 34 | class Mutex { 35 | public: 36 | #ifdef CMAKE_USE_PTHREADS_INIT 37 | pthread_mutex_t _mutex; 38 | Mutex() { pthread_mutex_init(&_mutex, 0); } 39 | ~Mutex() { pthread_mutex_destroy(&_mutex); } 40 | #endif 41 | 42 | void lock(); 43 | void unlock(); 44 | }; 45 | 46 | class Lock { 47 | public: 48 | explicit Lock(Mutex &mutex); 49 | ~Lock(); 50 | 51 | // leave the lock as it is. When the Lock wrapper is destroyed, it 52 | // will do nothing with the pthread mutex. 53 | void leave(); 54 | 55 | private: 56 | Lock(const Lock &src); // not allowed 57 | Lock &operator=(const Lock &src); // not allowed 58 | 59 | Mutex *_mutex; 60 | }; 61 | 62 | inline void Mutex::lock() { 63 | #ifdef CMAKE_USE_PTHREADS_INIT 64 | pthread_mutex_lock(&_mutex); 65 | #endif 66 | } 67 | 68 | inline void Mutex::unlock() { 69 | #ifdef CMAKE_USE_PTHREADS_INIT 70 | pthread_mutex_unlock(&_mutex); 71 | #endif 72 | } 73 | 74 | inline Lock::Lock(Mutex &mutex) : _mutex(&mutex) { 75 | if (_mutex) _mutex->lock(); 76 | } 77 | 78 | inline Lock::~Lock() { 79 | if (_mutex) _mutex->unlock(); 80 | } 81 | 82 | inline void Lock::leave() { _mutex = NULL; } 83 | 84 | } // namespace encfs 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /fs/BlockNameIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _BlockNameIO_incl_ 22 | #define _BlockNameIO_incl_ 23 | 24 | #include "fs/NameIO.h" 25 | 26 | #include 27 | #include 28 | 29 | namespace encfs { 30 | 31 | class CipherV1; 32 | 33 | /* 34 | Implement NameIO interface for filename encoding. Uses cipher in block 35 | mode to encode filenames. The filenames are padded to be a multiple of the 36 | cipher block size. 37 | */ 38 | class BlockNameIO : public NameIO { 39 | public: 40 | static Interface CurrentInterface(bool caseSensitive = false); 41 | 42 | BlockNameIO(const Interface &iface, const shared_ptr &cipher, 43 | bool caseSensitiveEncoding = false); 44 | virtual ~BlockNameIO(); 45 | 46 | virtual Interface interface() const override; 47 | 48 | virtual int maxEncodedNameLen(int plaintextNameLen) const override; 49 | virtual int maxDecodedNameLen(int encodedNameLen) const override; 50 | 51 | // hack to help with static builds 52 | static bool Enabled(); 53 | 54 | protected: 55 | virtual std::string encodeName(const std::string &plaintextName, 56 | uint64_t *iv) const override; 57 | virtual std::string decodeName(const std::string &encodedName, 58 | uint64_t *iv) const override; 59 | 60 | private: 61 | int _interface; 62 | int _bs; 63 | shared_ptr _cipher; 64 | bool _caseSensitive; 65 | }; 66 | 67 | } // namespace encfs 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /base/autosprintf.cpp: -------------------------------------------------------------------------------- 1 | /* Class autosprintf - formatted output to an ostream. 2 | Copyright (C) 2002 Free Software Foundation, Inc. 3 | Written by Bruno Haible , 2002. 4 | 5 | This program is free software; you can redistribute it and/or modify it 6 | under the terms of the GNU Library General Public License as published 7 | by the Free Software Foundation; either version 2, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Library General Public License for more details. 14 | 15 | You should have received a copy of the GNU Library General Public 16 | License along with this program; if not, write to the Free Software 17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 18 | USA. */ 19 | 20 | /* Tell glibc's to provide a prototype for vasprintf(). 21 | This must come before because may include 22 | , and once has been included, it's too late. */ 23 | #ifndef _GNU_SOURCE 24 | #define _GNU_SOURCE 1 25 | #endif 26 | 27 | /* Specification. */ 28 | #include "base/autosprintf.h" 29 | 30 | #include 31 | #include 32 | #include 33 | //#include "lib-asprintf.h" 34 | #include 35 | 36 | namespace gnu { 37 | 38 | /* Constructor: takes a format string and the printf arguments. */ 39 | autosprintf::autosprintf(const char *format, ...) { 40 | va_list args; 41 | va_start(args, format); 42 | if (vasprintf(&str, format, args) < 0) str = NULL; 43 | va_end(args); 44 | } 45 | 46 | /* Copy constructor. Necessary because the destructor is nontrivial. */ 47 | autosprintf::autosprintf(const autosprintf &src) { 48 | str = (src.str != NULL ? strdup(src.str) : NULL); 49 | } 50 | 51 | /* Destructor: frees the temporarily allocated string. */ 52 | autosprintf::~autosprintf() { free(str); } 53 | 54 | /* Conversion to string. */ 55 | autosprintf::operator char *() const { 56 | if (str != NULL) { 57 | size_t length = strlen(str) + 1; 58 | char *copy = new char[length]; 59 | memcpy(copy, str, length); 60 | return copy; 61 | } else 62 | return NULL; 63 | } 64 | autosprintf::operator std::string() const { 65 | return std::string(str ? str : "(error in autosprintf)"); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /cipher/readpassphrase.h: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: readpassphrase.h,v 1.1 2000/11/21 00:48:38 millert Exp $ 2 | */ 3 | 4 | /* 5 | * Copyright (c) 2000 Todd C. Miller 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 21 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _READPASSPHRASE_H_ 32 | #define _READPASSPHRASE_H_ 33 | 34 | //#include "includes.h" 35 | #include 36 | 37 | #ifndef HAVE_READPASSPHRASE 38 | 39 | #define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ 40 | #define RPP_ECHO_ON 0x01 /* Leave echo on. */ 41 | #define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ 42 | #define RPP_FORCELOWER 0x04 /* Force input to lower case. */ 43 | #define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ 44 | #define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ 45 | 46 | #ifdef __cplusplus 47 | extern "C" 48 | #endif 49 | char * 50 | readpassphrase(const char *prompt, char *buf, size_t bufSize, 51 | int flags); 52 | 53 | #endif /* HAVE_READPASSPHRASE */ 54 | 55 | #endif /* !_READPASSPHRASE_H_ */ 56 | -------------------------------------------------------------------------------- /base/autosprintf.h: -------------------------------------------------------------------------------- 1 | /* Class autosprintf - formatted output to an ostream. 2 | Copyright (C) 2002 Free Software Foundation, Inc. 3 | 4 | This program is free software; you can redistribute it and/or modify it 5 | under the terms of the GNU Library General Public License as published 6 | by the Free Software Foundation; either version 2, or (at your option) 7 | any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Library General Public License for more details. 13 | 14 | You should have received a copy of the GNU Library General Public 15 | License along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 17 | USA. */ 18 | 19 | #ifndef _AUTOSPRINTF_H 20 | #define _AUTOSPRINTF_H 21 | 22 | #ifndef __attribute__ 23 | /* This feature is available in gcc versions 2.5 and later. */ 24 | #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ 25 | #define __attribute__(Spec) /* empty */ 26 | #endif 27 | /* The __-protected variants of `format' and `printf' attributes 28 | are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ 29 | #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) 30 | #define __format__ format 31 | #define __printf__ printf 32 | #endif 33 | #endif 34 | 35 | #include 36 | #include 37 | 38 | namespace gnu { 39 | /* A temporary object, usually allocated on the stack, representing 40 | the result of an asprintf() call. */ 41 | class autosprintf { 42 | public: 43 | /* Constructor: takes a format string and the printf arguments. */ 44 | autosprintf(const char* format, ...) 45 | __attribute__((__format__(__printf__, 2, 3))); 46 | /* Copy constructor. */ 47 | autosprintf(const autosprintf& src); 48 | /* Destructor: frees the temporarily allocated string. */ 49 | ~autosprintf(); 50 | /* Conversion to string. */ 51 | operator char*() const; 52 | operator std::string() const; 53 | /* Output to an ostream. */ 54 | friend inline std::ostream& operator<<(std::ostream& stream, 55 | const autosprintf& tmp) { 56 | stream << (tmp.str ? tmp.str : "(error in autosprintf)"); 57 | return stream; 58 | } 59 | 60 | private: 61 | char* str; 62 | }; 63 | } 64 | 65 | #endif /* _AUTOSPRINTF_H */ 66 | -------------------------------------------------------------------------------- /fs/BlockFileIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _BlockFileIO_incl_ 22 | #define _BlockFileIO_incl_ 23 | 24 | #include "fs/FileIO.h" 25 | #include "fs/FSConfig.h" 26 | 27 | namespace encfs { 28 | 29 | /* 30 | Implements block scatter / gather interface. Requires derived classes to 31 | implement readOneBlock() / writeOneBlock() at a minimum. 32 | 33 | When a partial block write is requested it will be turned into a read of 34 | the existing block, merge with the write request, and a write of the full 35 | block. 36 | */ 37 | class BlockFileIO : public FileIO { 38 | public: 39 | BlockFileIO(int blockSize, const FSConfigPtr &cfg); 40 | virtual ~BlockFileIO(); 41 | 42 | // implemented in terms of blocks. 43 | virtual ssize_t read(const IORequest &req) const; 44 | virtual bool write(const IORequest &req); 45 | 46 | virtual int blockSize() const; 47 | 48 | protected: 49 | int blockTruncate(off_t size, FileIO *base); 50 | void padFile(off_t oldSize, off_t newSize, bool forceWrite); 51 | 52 | // same as read(), except that the request.offset field is guarenteed to be 53 | // block aligned, and the request size will not be larger then 1 block. 54 | virtual ssize_t readOneBlock(const IORequest &req) const = 0; 55 | virtual bool writeOneBlock(const IORequest &req) = 0; 56 | 57 | ssize_t cacheReadOneBlock(const IORequest &req) const; 58 | bool cacheWriteOneBlock(const IORequest &req); 59 | 60 | int _blockSize; 61 | bool _allowHoles; 62 | 63 | // cache last block for speed... 64 | mutable IORequest _cache; 65 | }; 66 | 67 | } // namespace encfs 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /base/ConfigVar.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _ConfigVar_incl_ 22 | #define _ConfigVar_incl_ 23 | 24 | #include 25 | #include "base/shared_ptr.h" 26 | #include "base/types.h" 27 | 28 | namespace encfs { 29 | 30 | class ConfigVar { 31 | struct ConfigVarData { 32 | std::string buffer; 33 | int offset; 34 | }; 35 | 36 | shared_ptr pd; 37 | 38 | public: 39 | ConfigVar(); 40 | ConfigVar(const std::string &buffer); 41 | ConfigVar(const ConfigVar &src); 42 | ~ConfigVar(); 43 | 44 | ConfigVar &operator=(const ConfigVar &src); 45 | 46 | // reset read/write offset.. 47 | void resetOffset(); 48 | 49 | // read bytes 50 | int read(byte *buffer, int size) const; 51 | 52 | // write bytes.. 53 | int write(const byte *data, int size); 54 | 55 | int readInt() const; 56 | int readInt(int defaultValue) const; 57 | void writeInt(int value); 58 | 59 | bool readBool(bool defaultValue) const; 60 | 61 | void writeString(const char *data, int size); 62 | 63 | // return amount of data in var 64 | int size() const; 65 | // return data pointer - returns front of data pointer, not the current 66 | // position. 67 | const char *buffer() const; 68 | 69 | // return current position in data() buffer. 70 | int at() const; 71 | }; 72 | 73 | ConfigVar &operator<<(ConfigVar &, bool); 74 | ConfigVar &operator<<(ConfigVar &, int); 75 | ConfigVar &operator<<(ConfigVar &, const std::string &str); 76 | 77 | const ConfigVar &operator>>(const ConfigVar &, bool &); 78 | const ConfigVar &operator>>(const ConfigVar &, int &); 79 | const ConfigVar &operator>>(const ConfigVar &, std::string &str); 80 | 81 | } // namespace encfs 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /base/Registry.h: -------------------------------------------------------------------------------- 1 | #ifndef REGISTRY_H 2 | #define REGISTRY_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace encfs { 9 | 10 | template 11 | class Registry { 12 | public: 13 | typedef T *(*FactoryFn)(); 14 | struct Data { 15 | FactoryFn constructor; 16 | typename T::Properties properties; 17 | }; 18 | 19 | void Register(const char *name, FactoryFn fn, 20 | typename T::Properties properties) { 21 | Data d; 22 | d.constructor = fn; 23 | d.properties = properties; 24 | data[name] = d; 25 | } 26 | 27 | T *Create(const char *name) { 28 | auto it = data.find(name); 29 | if (it == data.end()) return NULL; 30 | return (*it->second.constructor)(); 31 | } 32 | 33 | T *CreateForMatch(const std::string &description) { 34 | for (auto &it : data) { 35 | auto name = it.second.properties.toString(); 36 | if (!name.compare(0, description.size(), description)) 37 | return (*it.second.constructor)(); 38 | } 39 | return NULL; 40 | } 41 | 42 | std::list GetAll() const { 43 | std::list result; 44 | for (auto &it : data) { 45 | result.push_back(it.first); 46 | } 47 | return result; 48 | } 49 | 50 | const typename T::Properties *GetProperties(const char *name) const { 51 | auto it = data.find(name); 52 | if (it == data.end()) return NULL; 53 | return &(it->second.properties); 54 | } 55 | 56 | const typename T::Properties *GetPropertiesForMatch( 57 | const std::string &description) const { 58 | for (auto &it : data) { 59 | auto name = it.second.properties.toString(); 60 | if (!name.compare(0, description.size(), description)) 61 | return &(it.second.properties); 62 | } 63 | return NULL; 64 | } 65 | 66 | private: 67 | std::map data; 68 | }; 69 | 70 | template 71 | class Registrar { 72 | public: 73 | Registrar(const char *name) { 74 | BASE::GetRegistry().Register(name, Registrar::Construct, 75 | T::GetProperties()); 76 | } 77 | 78 | static BASE *Construct() { return new T(); } 79 | }; 80 | 81 | #define DECLARE_REGISTERABLE_TYPE(TYPE) static Registry &GetRegistry() 82 | 83 | #define DEFINE_REGISTERABLE_TYPE(TYPE) \ 84 | Registry &TYPE::GetRegistry() { \ 85 | static Registry registry; \ 86 | return registry; \ 87 | } 88 | 89 | #define REGISTER_CLASS(DERIVED, BASE) \ 90 | static Registrar registrar_##DERIVED##_##BASE(#DERIVED) 91 | 92 | } // namespace encfs 93 | 94 | #endif // REGISTRY_H 95 | -------------------------------------------------------------------------------- /base/Interface.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004-2013, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "base/Interface.h" 22 | 23 | #include "base/ConfigVar.h" 24 | 25 | #include 26 | #include 27 | 28 | namespace encfs { 29 | 30 | using std::string; 31 | using std::ostream; 32 | 33 | ostream &operator<<(ostream &out, const Interface &iface) { 34 | out << iface.name() << "(" << iface.major() << ":" << iface.minor() << ":" 35 | << iface.age() << ")"; 36 | return out; 37 | } 38 | 39 | bool implements(const Interface &A, const Interface &B) { 40 | VLOG(1) << "checking if " << A << " implements " << B; 41 | 42 | if (A.name() != B.name()) return false; 43 | 44 | int currentDiff = A.major() - B.major(); 45 | return (currentDiff >= 0 && currentDiff <= (int)A.age()); 46 | } 47 | 48 | Interface makeInterface(const string &name, int major, int minor, int age) { 49 | Interface iface; 50 | iface.set_name(name); 51 | iface.set_major(major); 52 | iface.set_minor(minor); 53 | iface.set_age(age); 54 | return iface; 55 | } 56 | 57 | ConfigVar &operator<<(ConfigVar &dst, const Interface &iface) { 58 | dst << iface.name() << (int)iface.major() << (int)iface.minor() 59 | << (int)iface.age(); 60 | return dst; 61 | } 62 | 63 | const ConfigVar &operator>>(const ConfigVar &src, Interface &iface) { 64 | src >> *iface.mutable_name(); 65 | int major, minor, age; 66 | src >> major >> minor >> age; 67 | iface.set_major(major); 68 | iface.set_minor(minor); 69 | iface.set_age(age); 70 | return src; 71 | } 72 | 73 | bool operator!=(const Interface &a, const Interface &b) { 74 | if (a.major() != b.major()) return true; 75 | 76 | if (a.minor() != b.minor()) return true; 77 | 78 | return false; 79 | } 80 | 81 | } // namespace encfs 82 | -------------------------------------------------------------------------------- /fs/FileIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _FileIO_incl_ 22 | #define _FileIO_incl_ 23 | 24 | #include "base/Interface.h" 25 | #include "fs/encfs.h" 26 | 27 | #include 28 | 29 | namespace encfs { 30 | 31 | struct IORequest { 32 | off_t offset; 33 | 34 | // amount of bytes to read/write. 35 | int dataLen; 36 | unsigned char *data; 37 | 38 | IORequest(); 39 | }; 40 | 41 | inline IORequest::IORequest() : offset(0), dataLen(0), data(0) {} 42 | 43 | class FileIO { 44 | public: 45 | FileIO(); 46 | virtual ~FileIO(); 47 | 48 | virtual Interface interface() const = 0; 49 | 50 | // default implementation returns 1, meaning this is not block oriented. 51 | virtual int blockSize() const; 52 | 53 | virtual void setFileName(const char *fileName) = 0; 54 | virtual const char *getFileName() const = 0; 55 | 56 | // Not sure about this -- it is specific to CipherFileIO, but the 57 | // alternative methods of exposing this interface aren't much nicer.. 58 | virtual bool setIV(uint64_t iv); 59 | 60 | // open file for specified mode. There is no corresponding close, so a 61 | // file is open until the FileIO interface is destroyed. 62 | virtual int open(int flags) = 0; 63 | 64 | // get filesystem attributes for a file 65 | virtual int getAttr(struct stat *stbuf) const = 0; 66 | virtual off_t getSize() const = 0; 67 | 68 | virtual ssize_t read(const IORequest &req) const = 0; 69 | virtual bool write(const IORequest &req) = 0; 70 | 71 | virtual int truncate(off_t size) = 0; 72 | 73 | virtual bool isWritable() const = 0; 74 | 75 | private: 76 | // not implemented.. 77 | FileIO(const FileIO &); 78 | FileIO &operator=(const FileIO &); 79 | }; 80 | 81 | } // namespace encfs 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /CMakeModules/FindGLog.cmake: -------------------------------------------------------------------------------- 1 | # Try to find the libglog libraries 2 | # Once done this will define : 3 | # 4 | # Glog_FOUND - system has libglog 5 | # Glog_INCLUDE_DIRS - the libglog include directory 6 | # Glog_LIBRARIES - libglog library 7 | 8 | # Inputs to this module: 9 | # GLOG_ROOT The preferred installation prefix for searching for glog. Set 10 | # this if the module has problems finding the proper glog installation. 11 | 12 | # If GLOG_ROOT was defined in the environment, use it. 13 | IF (NOT GLOG_ROOT AND NOT $ENV{GLOG_ROOT} STREQUAL "") 14 | SET(GLOG_ROOT $ENV{GLOG_ROOT}) 15 | ENDIF(NOT GLOG_ROOT AND NOT $ENV{GLOG_ROOT} STREQUAL "") 16 | IF( GLOG_ROOT ) 17 | file(TO_CMAKE_PATH ${GLOG_ROOT} GLOG_ROOT) 18 | ENDIF( GLOG_ROOT ) 19 | 20 | SET (GLOG_INCLUDE_DIRS) 21 | SET (GLOG_LIBRARIES) 22 | IF(WIN32) 23 | IF(MSVC) 24 | FIND_PATH(GLOG_INCLUDE_DIRS NAMES src/windows/glog/logging.h HINTS ${GLOG_ROOT}) 25 | IF(GLOG_INCLUDE_DIRS) 26 | SET(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS}/src/windows) 27 | ENDIF(GLOG_INCLUDE_DIRS) 28 | 29 | IF (CMAKE_BUILD_TYPE STREQUAL "Release") 30 | message (STATUS " searching ${GLOG_ROOT}/Release/libglog.lib ...") 31 | FIND_LIBRARY(GLOG_LIBRARIES NAMES libglog.lib HINTS ${GLOG_ROOT}/Release $ENV{LIB} PATH_SUFFIXES ".lib") 32 | ELSE (CMAKE_BUILD_TYPE STREQUAL "Release") 33 | message (STATUS " searching ${GLOG_ROOT}/Debug/libglog.lib ...") 34 | FIND_LIBRARY(GLOG_LIBRARIES NAMES libglog.lib HINTS ${GLOG_ROOT}/Debug $ENV{LIB} PATH_SUFFIXES ".lib") 35 | ENDIF (CMAKE_BUILD_TYPE STREQUAL "Release") 36 | ELSE(MSVC) 37 | SET(Glog_FOUND FALSE) 38 | message (STATUS " Crap. this module supports only MSVC in Windows.") 39 | ENDIF(MSVC) 40 | ELSE(WIN32) 41 | FIND_PATH(GLOG_INCLUDE_DIRS NAMES glog/logging.h HINTS ${GLOG_ROOT}/include ${GLOG_ROOT} /include/ /usr/include/ /usr/local/include/ /opt/local/include/) 42 | FIND_LIBRARY(GLOG_LIBRARIES NAMES glog HINTS ${GLOG_ROOT}/lib ${GLOG_ROOT} /lib /usr/lib /usr/local/lib /opt/local/lib) 43 | ENDIF(WIN32) 44 | 45 | IF(GLOG_INCLUDE_DIRS AND GLOG_LIBRARIES) 46 | SET(Glog_FOUND TRUE) 47 | message (STATUS " glog found in include=${GLOG_INCLUDE_DIRS},lib=${GLOG_LIBRARIES}") 48 | ELSE(GLOG_INCLUDE_DIRS AND GLOG_LIBRARIES) 49 | SET(Glog_FOUND FALSE) 50 | message (STATUS " glog not found. Please set GLOG_ROOT to the root directory containing glog.") 51 | IF(GLOG_INCLUDE_DIRS) 52 | message (STATUS " include=${GLOG_INCLUDE_DIRS}, but lib not found") 53 | ENDIF(GLOG_INCLUDE_DIRS) 54 | IF(GLOG_LIBRARIES) 55 | message (STATUS " lib=${GLOG_LIBRARIES}, but include not found") 56 | ENDIF(GLOG_LIBRARIES) 57 | ENDIF(GLOG_INCLUDE_DIRS AND GLOG_LIBRARIES) 58 | 59 | MARK_AS_ADVANCED(GLOG_INCLUDE_DIRS GLOG_LIBRARIES) 60 | -------------------------------------------------------------------------------- /cipher/MAC_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include "base/shared_ptr.h" 27 | #include "cipher/MAC.h" 28 | #include "cipher/testing.h" 29 | 30 | using namespace encfs; 31 | 32 | namespace { 33 | 34 | TEST(HMacSha1Test, MAC) { 35 | Registry registry = MAC::GetRegistry(); 36 | shared_ptr hmac(registry.CreateForMatch(NAME_SHA1_HMAC)); 37 | ASSERT_FALSE(!hmac); 38 | 39 | // Test cases from rfc2202 40 | // Test case 1 41 | CipherKey key(20); 42 | byte out[20]; 43 | for (int i = 0; i < 20; ++i) key.data()[i] = 0x0b; 44 | hmac->setKey(key); 45 | hmac->init(); 46 | hmac->update((byte *)"Hi There", 8); 47 | hmac->write(out); 48 | ASSERT_EQ("b617318655057264e28bc0b6fb378c8ef146be00", stringToHex(out, 20)); 49 | 50 | // Test case 2 51 | key = CipherKey((const byte *)"Jefe", 4); 52 | hmac->setKey(key); 53 | hmac->init(); 54 | hmac->update((byte *)"what do ya want for nothing?", 28); 55 | hmac->write(out); 56 | ASSERT_EQ("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", stringToHex(out, 20)); 57 | 58 | // Test case 3 59 | key = CipherKey(20); 60 | for (int i = 0; i < 20; ++i) key.data()[i] = 0xaa; 61 | hmac->setKey(key); 62 | hmac->init(); 63 | { 64 | byte data[50]; 65 | memset(data, 0xdd, 50); 66 | hmac->update(data, 50); 67 | } 68 | hmac->write(out); 69 | ASSERT_EQ("125d7342b9ac11cd91a39af48aa17b4f63f175d3", stringToHex(out, 20)); 70 | 71 | // Test #7 72 | key = CipherKey(80); 73 | memset(key.data(), 0xaa, 80); 74 | hmac->setKey(key); 75 | hmac->init(); 76 | hmac->update((byte *)"Test Using Larger Than Block-Size Key and Larger " 77 | "Than One Block-Size Data", 73); 78 | hmac->write(out); 79 | ASSERT_EQ("e8e99d0f45237d786d6bbaa7965c7808bbff1a91", stringToHex(out, 20)); 80 | } 81 | 82 | } // namespace 83 | -------------------------------------------------------------------------------- /fs/MemFileIO.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "fs/MemFileIO.h" 23 | 24 | #include "base/Error.h" 25 | 26 | #include 27 | 28 | namespace encfs { 29 | 30 | static Interface MemFileIO_iface = makeInterface("FileIO/Mem", 1, 0, 0); 31 | 32 | MemFileIO::MemFileIO(int size) : writable(false) { buf.resize(size); } 33 | 34 | MemFileIO::~MemFileIO() {} 35 | 36 | Interface MemFileIO::interface() const { return MemFileIO_iface; } 37 | 38 | void MemFileIO::setFileName(const char* name) { this->name = name; } 39 | 40 | const char* MemFileIO::getFileName() const { return name.c_str(); } 41 | 42 | int MemFileIO::open(int flags) { 43 | bool requestWrite = ((flags & O_RDWR) || (flags & O_WRONLY)); 44 | 45 | writable = writable || requestWrite; 46 | LOG(ERROR) << "returning fake file descriptor"; 47 | return 0; 48 | } 49 | 50 | int MemFileIO::getAttr(struct stat* stbuf) const { 51 | stbuf->st_size = buf.size(); 52 | return 0; 53 | } 54 | 55 | off_t MemFileIO::getSize() const { return buf.size(); } 56 | 57 | ssize_t MemFileIO::read(const IORequest& req) const { 58 | rAssert(req.offset >= 0); 59 | 60 | int len = req.dataLen; 61 | if (req.offset + req.dataLen > getSize()) { 62 | len = getSize() - req.offset; 63 | } 64 | if (len < 0) { 65 | len = 0; 66 | } 67 | 68 | memcpy(req.data, &buf[req.offset], len); 69 | return len; 70 | } 71 | 72 | bool MemFileIO::write(const IORequest& req) { 73 | rAssert(req.offset >= 0); 74 | if (req.offset + req.dataLen > getSize()) { 75 | truncate(req.offset + req.dataLen); 76 | } 77 | rAssert(req.offset + req.dataLen <= getSize()); 78 | 79 | memcpy(&buf[req.offset], req.data, req.dataLen); 80 | return true; 81 | } 82 | 83 | int MemFileIO::truncate(off_t size) { 84 | buf.resize(size); 85 | return 0; 86 | } 87 | 88 | bool MemFileIO::isWritable() const { return writable; } 89 | 90 | } // namespace encfs 91 | -------------------------------------------------------------------------------- /fs/FSConfig.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2010 Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _FSConfig_incl_ 22 | #define _FSConfig_incl_ 23 | 24 | #include "base/Interface.h" 25 | #include "base/shared_ptr.h" 26 | #include "cipher/CipherKey.h" 27 | #include "fs/encfs.h" 28 | #include "fs/fsconfig.pb.h" 29 | 30 | #include 31 | 32 | namespace encfs { 33 | 34 | enum ConfigType { 35 | Config_None = 0, 36 | Config_Prehistoric, 37 | Config_V3 = 3, 38 | Config_V4 = 4, 39 | Config_V5 = 5, 40 | Config_V6 = 6, 41 | Config_V7 = 7 42 | }; 43 | 44 | struct EncFS_Opts; 45 | class CipherV1; 46 | class NameIO; 47 | 48 | CipherKey getUserKey(const EncfsConfig &config, bool useStdin); 49 | CipherKey getUserKey(const EncfsConfig &config, 50 | const std::string &passwordProgram, 51 | const std::string &rootDir); 52 | 53 | CipherKey getNewUserKey(EncfsConfig &config, bool useStdin, 54 | const std::string &program, const std::string &rootDir); 55 | 56 | shared_ptr getCipher(const EncfsConfig &cfg); 57 | shared_ptr getCipher(const Interface &iface, int keySize); 58 | 59 | // helpers for serializing to/from a stream 60 | std::ostream &operator<<(std::ostream &os, const EncfsConfig &cfg); 61 | std::istream &operator>>(std::istream &os, EncfsConfig &cfg); 62 | 63 | // Filesystem state 64 | struct FSConfig { 65 | shared_ptr config; 66 | shared_ptr opts; 67 | 68 | shared_ptr cipher; 69 | CipherKey key; 70 | shared_ptr nameCoding; 71 | 72 | bool forceDecode; // force decode on MAC block failures 73 | bool reverseEncryption; // reverse encryption operation 74 | 75 | bool idleTracking; // turn on idle monitoring of filesystem 76 | 77 | FSConfig() 78 | : forceDecode(false), reverseEncryption(false), idleTracking(false) {} 79 | }; 80 | 81 | typedef shared_ptr FSConfigPtr; 82 | 83 | } // namespace encfs 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /base/base64.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2002-2003, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _base64_incl_ 22 | #define _base64_incl_ 23 | 24 | #include "base/types.h" 25 | 26 | namespace encfs { 27 | 28 | inline int B64ToB256Bytes(int numB64Bytes) { 29 | return (numB64Bytes * 6) / 8; // round down 30 | } 31 | 32 | inline int B32ToB256Bytes(int numB32Bytes) { 33 | return (numB32Bytes * 5) / 8; // round down 34 | } 35 | 36 | inline int B256ToB64Bytes(int numB256Bytes) { 37 | return (numB256Bytes * 8 + 5) / 6; // round up 38 | } 39 | 40 | inline int B256ToB32Bytes(int numB256Bytes) { 41 | return (numB256Bytes * 8 + 4) / 5; // round up 42 | } 43 | 44 | /* 45 | convert data between different bases - each being a power of 2. 46 | */ 47 | void changeBase2(byte *src, int srcLength, int srcPow2, byte *dst, 48 | int dstLength, int dstPow2); 49 | 50 | /* 51 | same as changeBase2, but writes output over the top of input data. 52 | */ 53 | void changeBase2Inline(byte *buf, int srcLength, int srcPow2, int dst2Pow, 54 | bool outputPartialLastByte); 55 | 56 | // inplace translation from values [0,2^6] => base64 ASCII 57 | // This is a nonstandard B64 encoding, which uses ',' and '-' as 58 | // non-alphanumeric chars. 59 | void B64ToAscii(byte *buf, int length); 60 | // inplace translation from values [0,2^5] => base32 ASCII 61 | void B32ToAscii(byte *buf, int length); 62 | 63 | // inplace translation from values base64 ASCII => [0,2^6] 64 | // This is a nonstandard B64 encoding, which uses ',' and '-' as 65 | // non-alphanumeric chars. 66 | void AsciiToB64(byte *buf, int length); 67 | 68 | // inplace translation from values base32 ASCII => [0,2^5] 69 | void AsciiToB32(byte *buf, int length); 70 | 71 | // Decode standard B64 into the output array. 72 | // Used only to decode legacy Boost XML serialized config format. 73 | // The output size must be at least B64ToB256Bytes(inputLen). 74 | bool B64StandardDecode(byte *out, const byte *in, int inputLen); 75 | 76 | } // namespace encfs 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /fs/CipherFileIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _CipherFileIO_incl_ 22 | #define _CipherFileIO_incl_ 23 | 24 | #include "cipher/CipherKey.h" 25 | #include "fs/BlockFileIO.h" 26 | #include "fs/FileUtils.h" 27 | 28 | #include 29 | 30 | namespace encfs { 31 | 32 | class CipherV1; 33 | 34 | /* 35 | Implement the FileIO interface encrypting data in blocks. 36 | 37 | Uses BlockFileIO to handle the block scatter / gather issues. 38 | */ 39 | class CipherFileIO : public BlockFileIO { 40 | public: 41 | CipherFileIO(const shared_ptr &base, const FSConfigPtr &cfg); 42 | virtual ~CipherFileIO(); 43 | 44 | virtual Interface interface() const; 45 | 46 | virtual void setFileName(const char *fileName); 47 | virtual const char *getFileName() const; 48 | virtual bool setIV(uint64_t iv); 49 | 50 | virtual int open(int flags); 51 | 52 | virtual int getAttr(struct stat *stbuf) const; 53 | virtual off_t getSize() const; 54 | 55 | // NOTE: if truncate is used to extend the file, the extended plaintext is 56 | // not 0. The extended ciphertext may be 0, resulting in non-zero 57 | // plaintext. 58 | virtual int truncate(off_t size); 59 | 60 | virtual bool isWritable() const; 61 | 62 | private: 63 | virtual ssize_t readOneBlock(const IORequest &req) const; 64 | virtual bool writeOneBlock(const IORequest &req); 65 | 66 | void initHeader(); 67 | bool writeHeader(); 68 | bool blockRead(unsigned char *buf, int size, uint64_t iv64) const; 69 | bool streamRead(unsigned char *buf, int size, uint64_t iv64) const; 70 | bool blockWrite(unsigned char *buf, int size, uint64_t iv64) const; 71 | bool streamWrite(unsigned char *buf, int size, uint64_t iv64) const; 72 | 73 | off_t adjustedSize(off_t size) const; 74 | 75 | shared_ptr base; 76 | 77 | FSConfigPtr fsConfig; 78 | 79 | // if haveHeader is true, then we have a transparent file header which 80 | int headerLen; 81 | 82 | bool perFileIV; 83 | uint64_t externalIV; 84 | uint64_t fileIV; 85 | int lastFlags; 86 | 87 | shared_ptr cipher; 88 | }; 89 | 90 | } // namespace encfs 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /base/Range.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _Range_incl_ 22 | #define _Range_incl_ 23 | 24 | #include 25 | 26 | namespace encfs { 27 | 28 | class Range { 29 | int minVal; 30 | int maxVal; 31 | int increment; 32 | 33 | public: 34 | Range(); 35 | Range(int minMax); 36 | Range(int min, int max, int increment); 37 | 38 | bool allowed(int value) const; 39 | 40 | int closest(int value) const; 41 | 42 | int min() const; 43 | int max() const; 44 | int inc() const; 45 | }; 46 | 47 | inline std::ostream &operator<<(std::ostream &st, const Range &r) { 48 | bool separator = false; 49 | for (int size = r.min(); size <= r.max(); size += r.inc()) { 50 | if (separator) 51 | st << ", "; 52 | else 53 | separator = true; 54 | st << size; 55 | } 56 | return st; 57 | } 58 | 59 | inline Range::Range(int minMax) { 60 | this->minVal = minMax; 61 | this->maxVal = minMax; 62 | this->increment = 1; 63 | } 64 | 65 | inline Range::Range(int min_, int max_, int increment_) { 66 | this->minVal = min_; 67 | this->maxVal = max_; 68 | this->increment = increment_; 69 | if (increment == 0) this->increment = 1; 70 | } 71 | 72 | inline Range::Range() : minVal(-1), maxVal(-1), increment(1) {} 73 | 74 | inline bool Range::allowed(int value) const { 75 | if (minVal < 0 && maxVal < 0) return true; 76 | if (value >= minVal && value <= maxVal) { 77 | int tmp = value - minVal; 78 | if ((tmp % increment) == 0) return true; 79 | } 80 | return false; 81 | } 82 | 83 | inline int Range::closest(int value) const { 84 | if (allowed(value)) 85 | return value; 86 | else if (value < minVal) 87 | return minVal; 88 | else if (value > maxVal) 89 | return maxVal; 90 | 91 | // must be inbetween but not matched with increment 92 | int tmp = value - minVal; 93 | // try rounding to the nearest increment.. 94 | tmp += (increment >> 1); 95 | tmp -= (tmp % increment); 96 | 97 | return closest(value + tmp); 98 | } 99 | 100 | inline int Range::min() const { return minVal; } 101 | 102 | inline int Range::max() const { return maxVal; } 103 | 104 | inline int Range::inc() const { return increment; } 105 | 106 | } // namespace encfs 107 | #endif 108 | -------------------------------------------------------------------------------- /base/ConfigReader.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004-2013, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "base/ConfigReader.h" 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "base/types.h" 32 | 33 | using std::make_pair; 34 | using std::map; 35 | using std::string; 36 | 37 | namespace encfs { 38 | 39 | ConfigReader::ConfigReader() {} 40 | 41 | ConfigReader::~ConfigReader() {} 42 | 43 | // read the entire file into a ConfigVar instance and then use that to decode 44 | // into mapped variables. 45 | bool ConfigReader::load(const char *fileName) { 46 | struct stat stbuf; 47 | memset(&stbuf, 0, sizeof(struct stat)); 48 | if (lstat(fileName, &stbuf) != 0) return false; 49 | 50 | int size = stbuf.st_size; 51 | 52 | int fd = open(fileName, O_RDONLY); 53 | if (fd < 0) return false; 54 | 55 | char *buf = new char[size]; 56 | 57 | int res = ::read(fd, buf, size); 58 | close(fd); 59 | 60 | if (res != size) { 61 | LOG(WARNING) << "Partial read of config file, expecting " << size 62 | << " bytes, got " << res; 63 | delete[] buf; 64 | return false; 65 | } 66 | 67 | ConfigVar in; 68 | in.write((byte *)buf, size); 69 | delete[] buf; 70 | 71 | return loadFromVar(in); 72 | } 73 | 74 | bool ConfigReader::loadFromVar(ConfigVar &in) { 75 | in.resetOffset(); 76 | 77 | // parse. 78 | int numEntries = in.readInt(); 79 | 80 | for (int i = 0; i < numEntries; ++i) { 81 | string key, value; 82 | in >> key >> value; 83 | 84 | if (key.length() == 0) { 85 | LOG(ERROR) << "Invalid key encoding in buffer"; 86 | return false; 87 | } 88 | ConfigVar newVar(value); 89 | vars.insert(make_pair(key, newVar)); 90 | } 91 | 92 | return true; 93 | } 94 | 95 | ConfigVar ConfigReader::operator[](const std::string &varName) const { 96 | // read only 97 | map::const_iterator it = vars.find(varName); 98 | if (it == vars.end()) 99 | return ConfigVar(); 100 | else 101 | return it->second; 102 | } 103 | 104 | ConfigVar &ConfigReader::operator[](const std::string &varName) { 105 | return vars[varName]; 106 | } 107 | 108 | } // namespace encfs 109 | -------------------------------------------------------------------------------- /fs/FileNode.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2003, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _FileNode_incl_ 22 | #define _FileNode_incl_ 23 | 24 | #include "base/Mutex.h" 25 | #include "cipher/CipherKey.h" 26 | #include "fs/encfs.h" 27 | #include "fs/FileUtils.h" 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | namespace encfs { 34 | 35 | class Cipher; 36 | class FileIO; 37 | class DirNode; 38 | 39 | class FileNode { 40 | public: 41 | FileNode(DirNode *parent, const FSConfigPtr &cfg, const char *plaintextName, 42 | const char *cipherName); 43 | ~FileNode(); 44 | 45 | const char *plaintextName() const; 46 | const char *cipherName() const; 47 | 48 | // directory portion of plaintextName 49 | std::string plaintextParent() const; 50 | 51 | // if setIVFirst is true, then the IV is changed before the name is changed 52 | // (default). The reverse is also supported for special cases.. 53 | bool setName(const char *plaintextName, const char *cipherName, uint64_t iv, 54 | bool setIVFirst = true); 55 | 56 | // create node 57 | // If uid/gid are not 0, then chown is used change ownership as specified 58 | int mknod(mode_t mode, dev_t rdev, uid_t uid = 0, gid_t gid = 0); 59 | 60 | // Returns < 0 on error (-errno), file descriptor on success. 61 | int open(int flags) const; 62 | 63 | // getAttr returns 0 on success, -errno on failure 64 | int getAttr(struct stat *stbuf) const; 65 | off_t getSize() const; 66 | 67 | ssize_t read(off_t offset, unsigned char *data, ssize_t size) const; 68 | bool write(off_t offset, unsigned char *data, ssize_t size); 69 | 70 | // truncate the file to a particular size 71 | int truncate(off_t size); 72 | 73 | // datasync or full sync 74 | int sync(bool dataSync); 75 | 76 | private: 77 | // doing locking at the FileNode level isn't as efficient as at the 78 | // lowest level of RawFileIO, since that means locks are held longer 79 | // (held during CPU intensive crypto operations!). However it makes it 80 | // easier to avoid any race conditions with operations such as 81 | // truncate() which may result in multiple calls down to the FileIO 82 | // level. 83 | mutable Mutex mutex; 84 | 85 | FSConfigPtr fsConfig; 86 | 87 | shared_ptr io; 88 | std::string _pname; // plaintext name 89 | std::string _cname; // encrypted name 90 | DirNode *parent; 91 | 92 | private: 93 | FileNode(const FileNode &src); 94 | FileNode &operator=(const FileNode &src); 95 | }; 96 | 97 | } // namespace encfs 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /fs/Context.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2007, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _Context_incl_ 22 | #define _Context_incl_ 23 | 24 | #include "base/config.h" 25 | #include "base/shared_ptr.h" 26 | #include "base/Mutex.h" 27 | 28 | #include 29 | #include 30 | 31 | #ifdef HAVE_TR1_UNORDERED_MAP 32 | #include 33 | using std::tr1::unordered_map; 34 | #else 35 | #include 36 | using std::unordered_map; 37 | #endif 38 | 39 | namespace encfs { 40 | 41 | struct EncFS_Args; 42 | struct EncFS_Opts; 43 | class FileNode; 44 | class DirNode; 45 | 46 | class EncFS_Context { 47 | public: 48 | EncFS_Context(); 49 | ~EncFS_Context(); 50 | 51 | static shared_ptr getNode(void *ptr); 52 | shared_ptr lookupNode(const char *path); 53 | 54 | int getAndResetUsageCounter(); 55 | int openFileCount() const; 56 | 57 | void *putNode(const char *path, const shared_ptr &node); 58 | 59 | void eraseNode(const char *path, void *placeholder); 60 | 61 | void renameNode(const char *oldName, const char *newName); 62 | 63 | void setRoot(const shared_ptr &root); 64 | shared_ptr getRoot(int *err); 65 | bool isMounted() const; 66 | 67 | shared_ptr args; 68 | shared_ptr opts; 69 | bool publicFilesystem; 70 | 71 | // root path to cipher dir 72 | std::string rootCipherDir; 73 | 74 | // for idle monitor 75 | bool running; 76 | 77 | #ifdef CMAKE_USE_PTHREADS_INIT 78 | pthread_t monitorThread; 79 | pthread_cond_t wakeupCond; 80 | Mutex wakeupMutex; 81 | #endif 82 | 83 | private: 84 | /* This placeholder is what is referenced in FUSE context (passed to 85 | * callbacks). 86 | * 87 | * A FileNode may be opened many times, but only one FileNode instance per 88 | * file is kept. Rather then doing reference counting in FileNode, we 89 | * store a unique Placeholder for each open() until the corresponding 90 | * release() is called. shared_ptr then does our reference counting for 91 | * us. 92 | */ 93 | struct Placeholder { 94 | shared_ptr node; 95 | 96 | Placeholder(const shared_ptr &ptr) : node(ptr) {} 97 | }; 98 | 99 | // set of open files, indexed by path 100 | typedef unordered_map > FileMap; 101 | 102 | #ifdef CMAKE_USE_PTHREADS_INIT 103 | mutable Mutex contextMutex; 104 | #endif 105 | 106 | FileMap openFiles; 107 | 108 | int usageCount; 109 | shared_ptr root; 110 | }; 111 | 112 | int remountFS(EncFS_Context *ctx); 113 | 114 | } // namespace encfs 115 | 116 | #endif 117 | -------------------------------------------------------------------------------- /fs/IO_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | #include "fs/testing.h" 26 | 27 | #include "cipher/MemoryPool.h" 28 | 29 | #include "fs/CipherFileIO.h" 30 | #include "fs/FileUtils.h" 31 | #include "fs/FSConfig.h" 32 | #include "fs/MACFileIO.h" 33 | #include "fs/MemFileIO.h" 34 | 35 | using namespace encfs; 36 | 37 | namespace { 38 | 39 | TEST(MemIOTest, BasicIO) { 40 | MemFileIO io(1024); 41 | ASSERT_EQ(1024, io.getSize()); 42 | 43 | MemBlock mb; 44 | mb.allocate(256); 45 | 46 | IORequest req; 47 | req.offset = 0; 48 | req.data = mb.data; 49 | req.dataLen = 256; 50 | 51 | for (int i = 0; i < 4; i++) { 52 | req.offset = i * 256; 53 | memset(req.data, 0, req.dataLen); 54 | ASSERT_TRUE(io.write(req)); 55 | } 56 | 57 | for (int i = 0; i < 4; i++) { 58 | req.offset = i * 256; 59 | ASSERT_EQ(req.dataLen, io.read(req)); 60 | } 61 | } 62 | 63 | void testMacIO(FSConfigPtr& cfg) { 64 | shared_ptr base(new MemFileIO(0)); 65 | shared_ptr test(new MACFileIO(base, cfg)); 66 | 67 | shared_ptr dup(new MemFileIO(0)); 68 | comparisonTest(cfg, test.get(), dup.get()); 69 | } 70 | 71 | TEST(IOTest, NullMacIO) { runWithCipher("Null", 512, testMacIO); } 72 | 73 | TEST(IOTest, MacIO) { runWithAllCiphers(testMacIO); } 74 | 75 | void testBasicCipherIO(FSConfigPtr& cfg) { 76 | shared_ptr base(new MemFileIO(0)); 77 | shared_ptr test(new CipherFileIO(base, cfg)); 78 | 79 | byte buf[1024]; 80 | cfg->cipher->pseudoRandomize(buf, sizeof(buf)); 81 | 82 | IORequest req; 83 | req.data = new byte[sizeof(buf)]; 84 | req.offset = 0; 85 | req.dataLen = sizeof(buf); 86 | 87 | memcpy(req.data, buf, sizeof(buf)); 88 | ASSERT_TRUE(test->write(req)); 89 | 90 | memset(req.data, 0, sizeof(buf)); 91 | ASSERT_EQ(req.dataLen, test->read(req)); 92 | 93 | for (unsigned int i = 0; i < sizeof(buf); ++i) { 94 | bool match = (buf[i] == req.data[i]); 95 | ASSERT_TRUE(match) << "mismatched data at offset " << i; 96 | if (!match) break; 97 | } 98 | 99 | delete[] req.data; 100 | } 101 | 102 | TEST(IOTest, BasicCipherFileIO) { runWithAllCiphers(testBasicCipherIO); } 103 | 104 | void testCipherIO(FSConfigPtr& cfg) { 105 | shared_ptr base(new MemFileIO(0)); 106 | shared_ptr test(new CipherFileIO(base, cfg)); 107 | 108 | shared_ptr dup(new MemFileIO(0)); 109 | comparisonTest(cfg, test.get(), dup.get()); 110 | } 111 | 112 | TEST(IOTest, NullCipherFileIO) { runWithCipher("Null", 512, testCipherIO); } 113 | 114 | TEST(IOTest, CipherFileIO) { runWithAllCiphers(testCipherIO); } 115 | 116 | } // namespace 117 | -------------------------------------------------------------------------------- /cipher/PBKDF_test.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2013 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include 23 | 24 | #include 25 | 26 | #include "base/shared_ptr.h" 27 | #include "cipher/PBKDF.h" 28 | #include "cipher/testing.h" 29 | 30 | using namespace encfs; 31 | 32 | namespace { 33 | 34 | TEST(PKCS5_PBKDF2_HMAC_SHA1, PBKDF) { 35 | Registry registry = PBKDF::GetRegistry(); 36 | shared_ptr impl(registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA1)); 37 | ASSERT_FALSE(!impl); 38 | 39 | // Test cases from rfc6070 40 | // Test case 1 41 | { 42 | CipherKey key(20); 43 | bool ok = impl->makeKey("password", 8, (byte*)"salt", 4, 1, &key); 44 | ASSERT_TRUE(ok); 45 | ASSERT_EQ("0c60c80f961f0e71f3a9b524af6012062fe037a6", stringToHex(key)); 46 | } 47 | 48 | { 49 | CipherKey key(25); 50 | bool ok = impl->makeKey("passwordPASSWORDpassword", 24, 51 | (byte*)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 52 | 4096, &key); 53 | ASSERT_TRUE(ok); 54 | ASSERT_EQ("3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", 55 | stringToHex(key)); 56 | } 57 | 58 | { 59 | CipherKey key(16); 60 | bool ok = impl->makeKey("pass\0word", 9, (byte*)"sa\0lt", 5, 4096, &key); 61 | ASSERT_TRUE(ok); 62 | ASSERT_EQ("56fa6aa75548099dcc37d7f03425e0c3", stringToHex(key)); 63 | } 64 | } 65 | 66 | TEST(PKCS5_PBKDF2_HMAC_SHA256, PBKDF) { 67 | Registry registry = PBKDF::GetRegistry(); 68 | shared_ptr impl(registry.CreateForMatch(NAME_PBKDF2_HMAC_SHA256)); 69 | ASSERT_FALSE(!impl); 70 | 71 | // Test case 1 72 | { 73 | CipherKey key(32); 74 | bool ok = impl->makeKey("password", 8, (byte*)"salt", 4, 1, &key); 75 | ASSERT_TRUE(ok); 76 | ASSERT_EQ( 77 | "120fb6cffcf8b32c" 78 | "43e7225256c4f837" 79 | "a86548c92ccc3548" 80 | "0805987cb70be17b", 81 | stringToHex(key)); 82 | } 83 | 84 | // Test case 2 85 | { 86 | CipherKey key(40); 87 | bool ok = impl->makeKey("passwordPASSWORDpassword", 24, 88 | (byte*)"saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 89 | 4096, &key); 90 | ASSERT_TRUE(ok); 91 | ASSERT_EQ( 92 | "348c89dbcbd32b2f" 93 | "32d814b8116e84cf" 94 | "2b17347ebc180018" 95 | "1c4e2a1fb8dd53e1" 96 | "c635518c7dac47e9", 97 | stringToHex(key)); 98 | } 99 | 100 | // Test case 3 101 | { 102 | CipherKey key(16); 103 | bool ok = impl->makeKey("pass\0word", 9, (byte*)"sa\0lt", 5, 4096, &key); 104 | ASSERT_TRUE(ok); 105 | ASSERT_EQ("89b69d0516f829893c696226650a8687", stringToHex(key)); 106 | } 107 | } 108 | 109 | } // namespace 110 | -------------------------------------------------------------------------------- /cipher/MemoryPool.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2003-2013, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "cipher/MemoryPool.h" 22 | 23 | #include 24 | #include 25 | 26 | #include "base/config.h" 27 | #include "base/Error.h" 28 | 29 | #include 30 | 31 | #include 32 | 33 | #include 34 | 35 | #ifdef HAVE_VALGRIND_MEMCHECK_H 36 | #include 37 | #else 38 | #define VALGRIND_MAKE_MEM_NOACCESS(a, b) 39 | #define VALGRIND_MAKE_MEM_UNDEFINED(a, b) 40 | #endif 41 | 42 | #include 43 | #include 44 | 45 | #ifdef WITH_OPENSSL 46 | #include 47 | #include 48 | #endif 49 | 50 | #ifdef WITH_BOTAN 51 | #include 52 | #include 53 | #endif 54 | 55 | namespace encfs { 56 | 57 | #ifdef WITH_OPENSSL 58 | static byte *allocBlock(int size) { 59 | byte *block = (byte *)OPENSSL_malloc(size); 60 | return block; 61 | } 62 | 63 | static void freeBlock(byte *block, int size) { 64 | OPENSSL_cleanse(block, size); 65 | OPENSSL_free(block); 66 | } 67 | 68 | #else 69 | 70 | static byte *allocBlock(int size) { 71 | byte *block = new byte[size]; 72 | return block; 73 | } 74 | 75 | unsigned char cleanse_ctr = 0; 76 | static void freeBlock(byte *data, int len) { 77 | byte *p = data; 78 | size_t loop = len, ctr = cleanse_ctr; 79 | while (loop--) { 80 | *(p++) = (unsigned char)ctr; 81 | ctr += (17 + ((size_t)p & 0xF)); 82 | } 83 | // Try to ensure the compiler doesn't optimize away the loop. 84 | p = (byte *)memchr(data, (unsigned char)ctr, len); 85 | if (p) ctr += (63 + (size_t)p); 86 | cleanse_ctr = (unsigned char)ctr; 87 | delete[] data; 88 | } 89 | 90 | #endif 91 | 92 | void MemBlock::allocate(int size) { 93 | rAssert(size > 0); 94 | this->data = allocBlock(size); 95 | this->size = size; 96 | } 97 | 98 | MemBlock::~MemBlock() { freeBlock(data, size); } 99 | 100 | #ifdef WITH_BOTAN 101 | SecureMem::SecureMem(int len) 102 | : data_(new Botan::SecureVector(len)) { 103 | rAssert(len > 0); 104 | } 105 | 106 | SecureMem::~SecureMem() { 107 | #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1, 11, 0) 108 | data_->destroy(); 109 | #endif 110 | delete data_; 111 | } 112 | 113 | byte *SecureMem::data() const { return const_cast(data_->begin()); } 114 | 115 | int SecureMem::size() const { return data_->size(); } 116 | 117 | #else 118 | SecureMem::SecureMem(int len) { 119 | rAssert(len > 0); 120 | data_ = allocBlock(len); 121 | if (data_) { 122 | size_ = len; 123 | mlock(data_, size_); 124 | } else { 125 | size_ = 0; 126 | } 127 | } 128 | 129 | SecureMem::~SecureMem() { 130 | if (size_) { 131 | freeBlock(data_, size_); 132 | munlock(data_, size_); 133 | 134 | data_ = NULL; 135 | size_ = 0; 136 | } 137 | } 138 | #endif 139 | 140 | bool operator==(const SecureMem &a, const SecureMem &b) { 141 | return (a.size() == b.size()) && (memcmp(a.data(), b.data(), a.size()) == 0); 142 | } 143 | 144 | } // namespace encfs 145 | -------------------------------------------------------------------------------- /util/encfsctl.pod: -------------------------------------------------------------------------------- 1 | =cut 2 | Copyright (c) 2003-2004, Valient Gough 3 | All rights reserved. 4 | 5 | EncFS is free software; you can distribute it and/or modify it under the terms 6 | of the GNU General Public License (GPL), as published by the Free Software 7 | Foundation; either version 2 of the License, or (at your option) any later 8 | version. 9 | 10 | =pod 11 | 12 | =head1 NAME 13 | 14 | encfsctl - administrative tool for working with EncFS filesystems 15 | 16 | =head1 SYNOPSIS 17 | 18 | B [I I] 19 | 20 | B I 21 | 22 | B info I 23 | 24 | B passwd I 25 | 26 | B showcruft I 27 | 28 | B decode [--extpass=prog] I [encoded name ...] 29 | 30 | B encode [--extpass=prog] I [plaintext name ...] 31 | 32 | =head1 DESCRIPTION 33 | 34 | B is an administrative tool for working with EncFS filesystems. It 35 | is capable of changing the user supplied password, displaying basic information 36 | about an encrypted volume, and other related operations. 37 | 38 | =head1 COMMANDS 39 | 40 | =over 4 41 | 42 | =item B 43 | 44 | Display basic information about the filesystem. Takes a single argument, 45 | I, which is the root directory of the encrypted filesystem. The 46 | filesystem need not be mounted. B is also the default command if only a 47 | root directory is provided on the command line. 48 | 49 | =item B 50 | 51 | Allows changing the password of the encrypted filesystem. The user will be 52 | prompted for the existing password and the new password. 53 | 54 | =item B 55 | 56 | Recursively search through the entire volume and display all files which are 57 | not decodable (only checks filename encoding, not block MAC headers). This 58 | might be useful for cleanup in case you've made use of features which create 59 | files which are not decodable under the primary key. 60 | 61 | =item B 62 | 63 | Allows you to specify an encoded name on the command line, and displays 64 | decoded version. This is mostly useful for debugging, as debug messages always 65 | display encrypted filenames (to avoid leaking sensitive data through the debug 66 | channels). So this command provides a way to decode the filenames. 67 | 68 | The B<--extpass> option can be used to specify the program which returns the 69 | password - just like with encfs. 70 | 71 | If no names are specified on the command line, then a list of filenames will be 72 | read from stdin and decoded. 73 | 74 | =item B 75 | 76 | Allows you to specify a filename on the command line, and displays its 77 | encoded version. This is useful if e.g. you are taking a backup of an 78 | encrypted directory and would like to exclude some files. 79 | 80 | The B<--extpass> option can be used to specify the program which returns the 81 | password - just like with encfs. 82 | 83 | If no names are specified on the command line, then a list of filenames 84 | will be read from stdin and encoded. 85 | 86 | =back 87 | 88 | =head1 EXAMPLES 89 | 90 | Show information about an encrypted filesystem: 91 | 92 | % encfsctl info ~/.crypt 93 | 94 | Version 5 configuration; created by EncFS 1.1 (revision 20040504) 95 | Filesystem cipher: "ssl/aes" , version 2:1:1 96 | Filename encoding: "nameio/block" , version 3:0:1 97 | Key Size: 192 bits 98 | Block Size: 512 bytes 99 | Each file contains 8 byte header with unique IV data. 100 | Filesname encoded using IV chaining mode. 101 | 102 | =head1 DISCLAIMER 103 | 104 | This library is distributed in the hope that it will be useful, but WITHOUT ANY 105 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 106 | PARTICULAR PURPOSE. Please refer to the "COPYING" file distributed with 107 | B for complete details. 108 | 109 | =head1 AUTHORS 110 | 111 | EncFS was written by Valient Gough . 112 | 113 | =head1 SEE ALSO 114 | 115 | encfs(1) 116 | -------------------------------------------------------------------------------- /fs/NameIO.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _NameIO_incl_ 22 | #define _NameIO_incl_ 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "base/Interface.h" 30 | #include "base/shared_ptr.h" 31 | #include "base/types.h" 32 | 33 | namespace encfs { 34 | 35 | class CipherV1; 36 | 37 | class NameIO { 38 | public: 39 | typedef shared_ptr(*Constructor)(const Interface &iface, 40 | const shared_ptr &cipher); 41 | 42 | struct Algorithm { 43 | std::string name; 44 | std::string description; 45 | Interface iface; 46 | bool needsStreamMode; 47 | }; 48 | 49 | typedef std::list AlgorithmList; 50 | static AlgorithmList GetAlgorithmList(bool includeHidden = false); 51 | 52 | static shared_ptr New(const Interface &iface, 53 | const shared_ptr &cipher); 54 | static shared_ptr New(const std::string &name, 55 | const shared_ptr &cipher); 56 | 57 | static bool Register(const char *name, const char *description, 58 | const Interface &iface, Constructor constructor, 59 | bool needsStreamMode, bool hidden = false); 60 | 61 | NameIO(); 62 | virtual ~NameIO(); 63 | 64 | virtual Interface interface() const = 0; 65 | 66 | void setChainedNameIV(bool enable); 67 | bool getChainedNameIV() const; 68 | void setReverseEncryption(bool enable); 69 | bool getReverseEncryption() const; 70 | 71 | std::string encodePath(const std::string &plaintextPath) const; 72 | std::string decodePath(const std::string &encodedPath) const; 73 | 74 | std::string encodePath(const std::string &plaintextPath, uint64_t *iv) const; 75 | std::string decodePath(const std::string &encodedPath, uint64_t *iv) const; 76 | 77 | virtual int maxEncodedNameLen(int plaintextNameLen) const = 0; 78 | virtual int maxDecodedNameLen(int encodedNameLen) const = 0; 79 | 80 | std::string encodeName(const std::string &plaintextName) const; 81 | std::string decodeName(const std::string &encodedName) const; 82 | 83 | protected: 84 | // Encode & decode methods implemented by derived classes. 85 | virtual std::string encodeName(const std::string &name, 86 | uint64_t *iv) const = 0; 87 | virtual std::string decodeName(const std::string &name, 88 | uint64_t *iv) const = 0; 89 | 90 | private: 91 | std::string recodePath(const std::string &path, 92 | int (NameIO::*codingLen)(int) const, 93 | std::string (NameIO::*codingFunc)(const std::string &, 94 | uint64_t *) const, 95 | uint64_t *iv) const; 96 | 97 | std::string _encodePath(const std::string &plaintextPath, uint64_t *iv) const; 98 | std::string _decodePath(const std::string &encodedPath, uint64_t *iv) const; 99 | 100 | bool chainedNameIV; 101 | bool reverseEncryption; 102 | }; 103 | 104 | } // namespace encfs 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /fs/encfs.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2003, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _encfs_incl_ 22 | #define _encfs_incl_ 23 | 24 | #include "base/config.h" 25 | #include 26 | #include 27 | 28 | #if defined(HAVE_SYS_XATTR_H) | defined(HAVE_ATTR_XATTR_H) 29 | #define HAVE_XATTR 30 | #endif 31 | 32 | #ifndef linux 33 | #include 34 | 35 | static __inline int setfsuid(uid_t uid) { 36 | uid_t olduid = geteuid(); 37 | 38 | seteuid(uid); 39 | 40 | if (errno != EINVAL) errno = 0; 41 | 42 | return olduid; 43 | } 44 | 45 | static __inline int setfsgid(gid_t gid) { 46 | gid_t oldgid = getegid(); 47 | 48 | setegid(gid); 49 | 50 | if (errno != EINVAL) errno = 0; 51 | 52 | return oldgid; 53 | } 54 | #endif 55 | 56 | namespace encfs { 57 | 58 | int encfs_getattr(const char *path, struct stat *stbuf); 59 | int encfs_fgetattr(const char *path, struct stat *stbuf, 60 | struct fuse_file_info *fi); 61 | int encfs_readlink(const char *path, char *buf, size_t size); 62 | int encfs_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler); 63 | int encfs_mknod(const char *path, mode_t mode, dev_t rdev); 64 | int encfs_mkdir(const char *path, mode_t mode); 65 | int encfs_unlink(const char *path); 66 | int encfs_rmdir(const char *path); 67 | int encfs_symlink(const char *from, const char *to); 68 | int encfs_rename(const char *from, const char *to); 69 | int encfs_link(const char *from, const char *to); 70 | int encfs_chmod(const char *path, mode_t mode); 71 | int encfs_chown(const char *path, uid_t uid, gid_t gid); 72 | int encfs_truncate(const char *path, off_t size); 73 | int encfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi); 74 | int encfs_utime(const char *path, struct utimbuf *buf); 75 | int encfs_open(const char *path, struct fuse_file_info *info); 76 | int encfs_release(const char *path, struct fuse_file_info *info); 77 | int encfs_read(const char *path, char *buf, size_t size, off_t offset, 78 | struct fuse_file_info *info); 79 | int encfs_write(const char *path, const char *buf, size_t size, off_t offset, 80 | struct fuse_file_info *info); 81 | int encfs_statfs(const char *, struct statvfs *fst); 82 | int encfs_flush(const char *, struct fuse_file_info *info); 83 | int encfs_fsync(const char *path, int flags, struct fuse_file_info *info); 84 | 85 | #ifdef HAVE_XATTR 86 | 87 | #ifdef XATTR_ADD_OPT 88 | int encfs_setxattr(const char *path, const char *name, const char *value, 89 | size_t size, int flags, uint32_t position); 90 | int encfs_getxattr(const char *path, const char *name, char *value, size_t size, 91 | uint32_t position); 92 | #else 93 | int encfs_setxattr(const char *path, const char *name, const char *value, 94 | size_t size, int flags); 95 | int encfs_getxattr(const char *path, const char *name, char *value, 96 | size_t size); 97 | #endif 98 | 99 | int encfs_listxattr(const char *path, char *list, size_t size); 100 | int encfs_removexattr(const char *path, const char *name); 101 | #endif 102 | 103 | int encfs_utimens(const char *path, const struct timespec ts[2]); 104 | 105 | } // namespace encfs 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | project(Encfs C CXX) 3 | 4 | set (ENCFS_MAJOR 2) 5 | set (ENCFS_MINOR 0) 6 | set (ENCFS_VERSION "${ENCFS_MAJOR}.${ENCFS_MINOR}") 7 | 8 | option (BUILD_SHARED_LIBS "Build dynamic link libraries" OFF) 9 | 10 | option (WITH_OPENSSL "WithOpenSSL" OFF) 11 | option (WITH_COMMON_CRYPTO "WithCommonCrypto" OFF) 12 | option (WITH_BOTAN "WithBotan" ON) 13 | 14 | set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} 15 | "${CMAKE_SOURCE_DIR}/CMakeModules/") 16 | 17 | # Include Crypto checks here so that they can set values in config.h 18 | if (WITH_COMMON_CRYPTO) 19 | set (WITH_BOTAN OFF) 20 | set (WITH_OPENSSL OFF) 21 | 22 | find_library (SECURITY_FRAMEWORK Security) 23 | mark_as_advanced (SECURITY_FRAMEWORK) 24 | elseif (WITH_BOTAN) 25 | set (WITH_COMMON_CRYPTO OFF) 26 | set (WITH_OPENSSL OFF) 27 | 28 | find_package (Botan REQUIRED) 29 | elseif (WITH_OPENSSL) 30 | set (WITH_BOTAN OFF) 31 | set (WITH_COMMON_CRYPTO OFF) 32 | 33 | find_package (OpenSSL REQUIRED) 34 | include (OpenSSLTests) 35 | endif (WITH_COMMON_CRYPTO) 36 | 37 | # Tweak compiler flags. 38 | set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") 39 | 40 | include (CheckCXXCompilerFlag) 41 | check_cxx_compiler_flag (-std=c++11 HAVE_C11_FLAG) 42 | check_cxx_compiler_flag (-std=gnu++11 HAVE_GNU11_FLAG) 43 | 44 | if (HAVE_GNU11_FLAG) 45 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") 46 | elseif (HAVE_C11_FLAG) 47 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 48 | endif (HAVE_GNU11_FLAG) 49 | 50 | # Flume specific flags. 51 | find_package (FUSE REQUIRED) 52 | include_directories (${FUSE_INCLUDE_DIR}) 53 | add_definitions (-D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26) 54 | if (APPLE) 55 | add_definitions (-D__FreeBSD__=10) 56 | # XXX: Fall back to stdc++, due to clang 5.0.1 header file issues 57 | # (missing sys/endian.h, needed by standard c++ header files). 58 | set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7") 59 | endif (APPLE) 60 | 61 | # Packaging config. 62 | set (CPACK_PACKAGE_NAME "Encfs") 63 | set (CPACK_PACKAGE_VERSION_MAJOR ${ENCFS_MAJOR}) 64 | set (CPACK_PACKAGE_VERSION_MINOR ${ENCFS_MINOR}) 65 | set (CPACK_SOURCE_GENERATOR TGZ) 66 | set (CPACK_SOURCE_IGNORE_FILES 67 | "/_darcs/" 68 | "/build/") 69 | include (CPack) 70 | 71 | # Check for external files. 72 | include (CheckIncludeFileCXX) 73 | check_include_file_cxx (attr/xattr.h HAVE_ATTR_XATTR_H) 74 | check_include_file_cxx (sys/xattr.h HAVE_SYS_XATTR_H) 75 | 76 | check_include_file_cxx (tr1/memory HAVE_TR1_MEMORY) 77 | check_include_file_cxx (tr1/unordered_map HAVE_TR1_UNORDERED_MAP) 78 | check_include_file_cxx (tr1/unordered_set HAVE_TR1_UNORDERED_SET) 79 | check_include_file_cxx (tr1/tuple HAVE_TR1_TUPLE) 80 | 81 | check_include_file_cxx (valgrind/valgrind.h HAVE_VALGRIND_VALGRIND_H) 82 | check_include_file_cxx (valgrind/memcheck.h HAVE_VALGRIND_MEMCHECK_H) 83 | 84 | # Used with CommonCrypto 85 | check_include_file_cxx (Security/SecRandom.h HAVE_SEC_RANDOM_H) 86 | 87 | # Check if xattr functions take extra argument. 88 | include (CheckCXXSourceCompiles) 89 | CHECK_CXX_SOURCE_COMPILES ("#include 90 | #include 91 | int main() { getxattr(0,0,0,0,0,0); return 1; } " XATTR_ADD_OPT) 92 | 93 | include (CheckFunctionExists) 94 | check_function_exists(lchmod HAVE_LCHMOD) 95 | 96 | # Libraries or programs used for multiple modules. 97 | find_package (Protobuf REQUIRED) 98 | include_directories (${PROTOBUF_INCLUDE_DIR}) 99 | 100 | find_package (GLog REQUIRED) 101 | include_directories (${GLOG_INCLUDE_DIRS}) 102 | 103 | find_package (GFlags) 104 | if (GFLAGS_FOUND) 105 | include_directories (${GFLAGS_INCLUDE_DIRS}) 106 | set (GLOG_LIBRARIES ${GLOG_LIBRARIES} ${GFLAGS_LIBRARIES}) 107 | endif (GFLAGS_FOUND) 108 | 109 | find_package (Threads) 110 | 111 | set (CMAKE_THREAD_PREFER_PTHREAD) 112 | find_program (POD2MAN pod2man) 113 | 114 | find_package (GTest) 115 | if (GTEST_FOUND) 116 | include_directories(${GTEST_INCLUDE_DIR}) 117 | enable_testing() 118 | endif (GTEST_FOUND) 119 | 120 | # Prefix for encfs module includes. 121 | include_directories (${Encfs_BINARY_DIR}) 122 | include_directories (${Encfs_SOURCE_DIR}) 123 | 124 | # Subdirectories. 125 | add_subdirectory(base) 126 | add_subdirectory(cipher) 127 | add_subdirectory(fs) 128 | add_subdirectory(encfs) 129 | add_subdirectory(util) 130 | add_subdirectory(po) 131 | 132 | # Test target. 133 | if (GTEST_FOUND) 134 | add_custom_target (test COMMAND ${CMAKE_TEST_COMMAND} DEPENDS 135 | cipher/cipher-tests fs/fs-tests) 136 | endif (GTEST_FOUND) 137 | 138 | 139 | -------------------------------------------------------------------------------- /fs/FileUtils.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004-2012, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _FileUtils_incl_ 22 | #define _FileUtils_incl_ 23 | 24 | #include "base/Interface.h" 25 | #include "cipher/CipherKey.h" 26 | #include "fs/encfs.h" 27 | #include "fs/FSConfig.h" 28 | 29 | namespace encfs { 30 | 31 | // true if the path points to an existing node (of any type) 32 | bool fileExists(const char *fileName); 33 | // true if path is a directory 34 | bool isDirectory(const char *fileName); 35 | // true if starts with '/' 36 | bool isAbsolutePath(const char *fileName); 37 | // pointer to just after the last '/' 38 | const char *lastPathElement(const char *name); 39 | 40 | std::string parentDirectory(const std::string &path); 41 | 42 | // ask the user for permission to create the directory. If they say ok, then 43 | // do it and return true. 44 | bool userAllowMkdir(const char *dirPath, mode_t mode); 45 | bool userAllowMkdir(int promptno, const char *dirPath, mode_t mode); 46 | 47 | class CipherV1; 48 | class DirNode; 49 | 50 | struct EncFS_Root { 51 | shared_ptr cipher; 52 | CipherKey volumeKey; 53 | shared_ptr root; 54 | 55 | EncFS_Root(); 56 | ~EncFS_Root(); 57 | }; 58 | 59 | typedef shared_ptr RootPtr; 60 | 61 | enum ConfigMode { 62 | Config_Prompt, 63 | Config_Standard, 64 | Config_Paranoia 65 | }; 66 | 67 | struct EncFS_Opts { 68 | std::string rootDir; 69 | bool createIfNotFound; // create filesystem if not found 70 | bool idleTracking; // turn on idle monitoring of filesystem 71 | bool mountOnDemand; // mounting on-demand 72 | bool delayMount; // delay initial mount 73 | 74 | bool checkKey; // check crypto key decoding 75 | bool forceDecode; // force decode on MAC block failures 76 | 77 | std::string passwordProgram; // path to password program (or empty) 78 | bool useStdin; // read password from stdin rather then prompting 79 | bool annotate; // print annotation line prompt to stderr. 80 | 81 | bool ownerCreate; // set owner of new files to caller 82 | 83 | bool reverseEncryption; // Reverse encryption 84 | 85 | ConfigMode configMode; 86 | 87 | EncFS_Opts() { 88 | createIfNotFound = true; 89 | idleTracking = false; 90 | mountOnDemand = false; 91 | delayMount = false; 92 | checkKey = true; 93 | forceDecode = false; 94 | useStdin = false; 95 | annotate = false; 96 | ownerCreate = false; 97 | reverseEncryption = false; 98 | configMode = Config_Prompt; 99 | } 100 | }; 101 | 102 | /* 103 | Read existing config file. Looks for any supported configuration version. 104 | */ 105 | ConfigType readConfig(const std::string &rootDir, EncfsConfig &config); 106 | 107 | /* 108 | Save the configuration. Saves back as the same configuration type as was 109 | read from. 110 | */ 111 | bool saveConfig(const std::string &rootdir, const EncfsConfig &config); 112 | 113 | class EncFS_Context; 114 | 115 | RootPtr initFS(EncFS_Context *ctx, const shared_ptr &opts); 116 | 117 | RootPtr createConfig(EncFS_Context *ctx, const shared_ptr &opts); 118 | 119 | void showFSInfo(const EncfsConfig &config); 120 | 121 | bool readV4Config(const char *configFile, EncfsConfig &config, 122 | struct ConfigInfo *); 123 | 124 | bool readV5Config(const char *configFile, EncfsConfig &config, 125 | struct ConfigInfo *); 126 | 127 | bool readV6Config(const char *configFile, EncfsConfig &config, 128 | struct ConfigInfo *); 129 | 130 | bool readProtoConfig(const char *configFile, EncfsConfig &config, 131 | struct ConfigInfo *); 132 | 133 | } // namespace encfs 134 | #endif 135 | -------------------------------------------------------------------------------- /fs/Context.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2007, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "fs/Context.h" 22 | 23 | #include "base/Error.h" 24 | #include "fs/FileNode.h" 25 | #include "fs/FileUtils.h" 26 | #include "fs/DirNode.h" 27 | 28 | namespace encfs { 29 | 30 | EncFS_Context::EncFS_Context() : publicFilesystem(false), running(false) { 31 | #ifdef CMAKE_USE_PTHREADS_INIT 32 | pthread_cond_init(&wakeupCond, 0); 33 | #endif 34 | 35 | usageCount = 0; 36 | } 37 | 38 | EncFS_Context::~EncFS_Context() { 39 | #ifdef CMAKE_USE_PTHREADS_INIT 40 | pthread_cond_destroy(&wakeupCond); 41 | #endif 42 | 43 | // release all entries from map 44 | openFiles.clear(); 45 | } 46 | 47 | shared_ptr EncFS_Context::getRoot(int *errCode) { 48 | shared_ptr ret; 49 | do { 50 | { 51 | Lock lock(contextMutex); 52 | ret = root; 53 | ++usageCount; 54 | } 55 | 56 | if (!ret) { 57 | int res = remountFS(this); 58 | if (res != 0) { 59 | *errCode = res; 60 | break; 61 | } 62 | } 63 | } while (!ret); 64 | 65 | return ret; 66 | } 67 | 68 | void EncFS_Context::setRoot(const shared_ptr &r) { 69 | Lock lock(contextMutex); 70 | 71 | root = r; 72 | if (r) rootCipherDir = r->rootDirectory(); 73 | } 74 | 75 | bool EncFS_Context::isMounted() const { return root; } 76 | 77 | int EncFS_Context::getAndResetUsageCounter() { 78 | Lock lock(contextMutex); 79 | 80 | int count = usageCount; 81 | usageCount = 0; 82 | 83 | return count; 84 | } 85 | 86 | int EncFS_Context::openFileCount() const { 87 | Lock lock(contextMutex); 88 | 89 | return openFiles.size(); 90 | } 91 | 92 | shared_ptr EncFS_Context::lookupNode(const char *path) { 93 | Lock lock(contextMutex); 94 | 95 | FileMap::iterator it = openFiles.find(std::string(path)); 96 | if (it != openFiles.end()) { 97 | // all the items in the set point to the same node.. so just use the 98 | // first 99 | return (*it->second.begin())->node; 100 | } else { 101 | return shared_ptr(); 102 | } 103 | } 104 | 105 | void EncFS_Context::renameNode(const char *from, const char *to) { 106 | Lock lock(contextMutex); 107 | 108 | FileMap::iterator it = openFiles.find(std::string(from)); 109 | if (it != openFiles.end()) { 110 | std::set val = it->second; 111 | openFiles.erase(it); 112 | openFiles[std::string(to)] = val; 113 | } 114 | } 115 | 116 | shared_ptr EncFS_Context::getNode(void *pl) { 117 | Placeholder *ph = static_cast(pl); 118 | return ph->node; 119 | } 120 | 121 | void *EncFS_Context::putNode(const char *path, 122 | const shared_ptr &node) { 123 | Lock lock(contextMutex); 124 | Placeholder *pl = new Placeholder(node); 125 | openFiles[std::string(path)].insert(pl); 126 | 127 | return (void *)pl; 128 | } 129 | 130 | void EncFS_Context::eraseNode(const char *path, void *pl) { 131 | Lock lock(contextMutex); 132 | 133 | Placeholder *ph = static_cast(pl); 134 | 135 | FileMap::iterator it = openFiles.find(std::string(path)); 136 | rAssert(it != openFiles.end()); 137 | 138 | int rmCount = it->second.erase(ph); 139 | 140 | rAssert(rmCount == 1); 141 | 142 | // if no more references to this file, remove the record all together 143 | if (it->second.empty()) { 144 | // attempts to make use of shallow copy to clear memory used to hold 145 | // unencrypted filenames.. not sure this does any good.. 146 | std::string storedName = it->first; 147 | openFiles.erase(it); 148 | storedName.assign(storedName.length(), '\0'); 149 | } 150 | 151 | delete ph; 152 | } 153 | 154 | } // namespace encfs 155 | -------------------------------------------------------------------------------- /base/XmlReader.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2012-2013, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "base/XmlReader.h" 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include 35 | #include "base/base64.h" 36 | #include "base/Interface.h" 37 | #include "base/shared_ptr.h" 38 | 39 | namespace encfs { 40 | 41 | XmlValue::~XmlValue() {} 42 | 43 | XmlValuePtr XmlValue::operator[](const char *path) const { return find(path); } 44 | 45 | XmlValuePtr XmlValue::find(const char *path) const { 46 | LOG_FIRST_N(ERROR, 1) << "in XmlValue::find( " << path << ")"; 47 | return XmlValuePtr(); 48 | } 49 | 50 | bool XmlValue::read(const char *path, std::string *out) const { 51 | XmlValuePtr value = find(path); 52 | if (!value) return false; 53 | 54 | *out = value->text(); 55 | return true; 56 | } 57 | 58 | bool XmlValue::read(const char *path, int *out) const { 59 | XmlValuePtr value = find(path); 60 | if (!value) return false; 61 | 62 | *out = atoi(value->text().c_str()); 63 | return true; 64 | } 65 | 66 | bool XmlValue::read(const char *path, long *out) const { 67 | XmlValuePtr value = find(path); 68 | if (!value) return false; 69 | 70 | *out = atol(value->text().c_str()); 71 | return true; 72 | } 73 | 74 | bool XmlValue::read(const char *path, double *out) const { 75 | XmlValuePtr value = find(path); 76 | if (!value) return false; 77 | 78 | *out = atof(value->text().c_str()); 79 | return true; 80 | } 81 | 82 | bool XmlValue::read(const char *path, bool *out) const { 83 | XmlValuePtr value = find(path); 84 | if (!value) return false; 85 | 86 | *out = atoi(value->text().c_str()); 87 | return true; 88 | } 89 | 90 | bool XmlValue::readB64(const char *path, byte *data, int length) const { 91 | XmlValuePtr value = find(path); 92 | if (!value) return false; 93 | 94 | std::string s = value->text(); 95 | s.erase(std::remove_if(s.begin(), s.end(), ::isspace), s.end()); 96 | s.erase(s.find_last_not_of("=") + 1); 97 | 98 | int decodedSize = B64ToB256Bytes(s.size()); 99 | if (decodedSize != length) { 100 | LOG(ERROR) << "decoding bytes len " << s.size() << ", expecting output len " 101 | << length << ", got " << decodedSize; 102 | return false; 103 | } 104 | if (!B64StandardDecode(data, (byte *)s.data(), s.size())) { 105 | LOG(ERROR) << "B64 decode failure on " << s; 106 | return false; 107 | } 108 | 109 | return true; 110 | } 111 | 112 | bool XmlValue::read(const char *path, Interface *out) const { 113 | XmlValuePtr node = find(path); 114 | if (!node) return false; 115 | 116 | int major, minor; 117 | bool ok = node->read("name", out->mutable_name()) && 118 | node->read("major", &major) && node->read("minor", &minor); 119 | 120 | if (!ok) return false; 121 | 122 | out->set_major(major); 123 | out->set_minor(minor); 124 | return true; 125 | } 126 | 127 | std::string safeValueForNode(const TiXmlElement *element) { 128 | std::string value; 129 | if (element == NULL) return value; 130 | 131 | const TiXmlNode *child = element->FirstChild(); 132 | if (child) { 133 | const TiXmlText *childText = child->ToText(); 134 | if (childText) value = childText->Value(); 135 | } 136 | 137 | return value; 138 | } 139 | 140 | class XmlNode : virtual public XmlValue { 141 | const TiXmlElement *element; 142 | 143 | public: 144 | XmlNode(const TiXmlElement *element_) 145 | : XmlValue(safeValueForNode(element_)), element(element_) {} 146 | 147 | virtual ~XmlNode() {} 148 | 149 | virtual XmlValuePtr find(const char *name) const { 150 | if (name[0] == '@') { 151 | const char *value = element->Attribute(name + 1); 152 | if (value) 153 | return XmlValuePtr(new XmlValue(value)); 154 | else 155 | return XmlValuePtr(); 156 | } else { 157 | const TiXmlElement *el = element->FirstChildElement(name); 158 | if (el) 159 | return XmlValuePtr(new XmlNode(el)); 160 | else 161 | return XmlValuePtr(); 162 | } 163 | } 164 | }; 165 | 166 | struct XmlReader::XmlReaderData { 167 | shared_ptr doc; 168 | }; 169 | 170 | XmlReader::XmlReader() : pd(new XmlReaderData()) {} 171 | 172 | XmlReader::~XmlReader() {} 173 | 174 | bool XmlReader::load(const char *fileName) { 175 | pd->doc.reset(new TiXmlDocument(fileName)); 176 | 177 | return pd->doc->LoadFile(); 178 | } 179 | 180 | XmlValuePtr XmlReader::operator[](const char *name) const { 181 | TiXmlNode *node = pd->doc->FirstChild(name); 182 | if (node == NULL) { 183 | LOG(ERROR) << "Xml node " << name << " not found"; 184 | return XmlValuePtr(new XmlValue()); 185 | } 186 | 187 | TiXmlElement *element = node->ToElement(); 188 | if (element == NULL) { 189 | LOG(ERROR) << "Xml node " << name 190 | << " not element, type = " << node->Type(); 191 | return XmlValuePtr(new XmlValue()); 192 | } 193 | 194 | return XmlValuePtr(new XmlNode(element)); 195 | } 196 | 197 | } // namespace encfs 198 | -------------------------------------------------------------------------------- /fs/DirNode.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2003, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #ifndef _DirNode_incl_ 22 | #define _DirNode_incl_ 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "base/Mutex.h" 34 | #include "base/shared_ptr.h" 35 | #include "cipher/CipherKey.h" 36 | #include "fs/FileNode.h" 37 | #include "fs/NameIO.h" 38 | #include "fs/FSConfig.h" 39 | 40 | namespace encfs { 41 | 42 | class Cipher; 43 | class RenameOp; 44 | struct RenameEl; 45 | class EncFS_Context; 46 | 47 | class DirTraverse { 48 | public: 49 | DirTraverse(const shared_ptr &dirPtr, uint64_t iv, 50 | const shared_ptr &naming); 51 | DirTraverse(const DirTraverse &src); 52 | ~DirTraverse(); 53 | 54 | DirTraverse &operator=(const DirTraverse &src); 55 | 56 | // returns FALSE to indicate an invalid DirTraverse (such as when 57 | // an invalid directory is requested for traversal) 58 | bool valid() const; 59 | 60 | // return next plaintext filename 61 | // If fileType is not 0, then it is used to return the filetype (or 0 if 62 | // unknown) 63 | std::string nextPlaintextName(int *fileType = 0, ino_t *inode = 0); 64 | 65 | /* Return cipher name of next undecodable filename.. 66 | The opposite of nextPlaintextName(), as that skips undecodable names.. 67 | */ 68 | std::string nextInvalid(); 69 | 70 | private: 71 | shared_ptr dir; // struct DIR 72 | // initialization vector to use. Not very general purpose, but makes it 73 | // more efficient to support filename IV chaining.. 74 | uint64_t iv; 75 | shared_ptr naming; 76 | }; 77 | inline bool DirTraverse::valid() const { return dir != 0; } 78 | 79 | class DirNode { 80 | public: 81 | // sourceDir points to where raw files are stored 82 | DirNode(EncFS_Context *ctx, const std::string &sourceDir, 83 | const FSConfigPtr &config); 84 | ~DirNode(); 85 | 86 | // return the path to the root directory 87 | std::string rootDirectory() const; 88 | 89 | // find files 90 | shared_ptr lookupNode(const char *plaintextName, 91 | const char *requestor); 92 | 93 | /* 94 | Combined lookupNode + node->open() call. If the open fails, then the 95 | node is not retained. If the open succeeds, then the node is returned. 96 | */ 97 | shared_ptr openNode(const char *plaintextName, 98 | const char *requestor, int flags, 99 | int *openResult); 100 | 101 | std::string cipherPath(const char *plaintextPath); 102 | std::string cipherPathWithoutRoot(const char *plaintextPath); 103 | std::string plainPath(const char *cipherPath); 104 | 105 | // relative cipherPath is the same as cipherPath except that it doesn't 106 | // prepent the mount point. That it, it doesn't return a fully qualified 107 | // name, just a relative path within the encrypted filesystem. 108 | std::string relativeCipherPath(const char *plaintextPath); 109 | 110 | /* 111 | Returns true if file names are dependent on the parent directory name. 112 | If a directory name is changed, then all the filenames must also be 113 | changed. 114 | */ 115 | bool hasDirectoryNameDependency() const; 116 | 117 | // unlink the specified file 118 | int unlink(const char *plaintextName); 119 | 120 | // traverse directory 121 | DirTraverse openDir(const char *plainDirName); 122 | 123 | // uid and gid are used as the directory owner, only if not zero 124 | int mkdir(const char *plaintextPath, mode_t mode, uid_t uid = 0, 125 | gid_t gid = 0); 126 | 127 | int rename(const char *fromPlaintext, const char *toPlaintext); 128 | 129 | int link(const char *from, const char *to); 130 | 131 | // returns idle time of filesystem in seconds 132 | int idleSeconds(); 133 | 134 | protected: 135 | /* 136 | notify that a file is being renamed. 137 | This renames the internal node, if any. If the file is not open, then 138 | this call has no effect. 139 | Returns the FileNode if it was found. 140 | */ 141 | shared_ptr renameNode(const char *from, const char *to); 142 | shared_ptr renameNode(const char *from, const char *to, 143 | bool forwardMode); 144 | 145 | /* 146 | when directory IV chaining is enabled, a directory can't be renamed 147 | without renaming all its contents as well. recursiveRename should be 148 | called after renaming the directory, passing in the plaintext from and 149 | to paths. 150 | */ 151 | shared_ptr newRenameOp(const char *from, const char *to); 152 | 153 | private: 154 | friend class RenameOp; 155 | 156 | bool genRenameList(std::list &list, const char *fromP, 157 | const char *toP); 158 | 159 | shared_ptr findOrCreate(const char *plainName); 160 | 161 | Mutex mutex; 162 | 163 | EncFS_Context *ctx; 164 | 165 | // passed in as configuration 166 | std::string rootDir; 167 | FSConfigPtr fsConfig; 168 | 169 | shared_ptr naming; 170 | }; 171 | 172 | } // namespace encfs 173 | 174 | #endif 175 | -------------------------------------------------------------------------------- /base/ConfigVar.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "base/ConfigVar.h" 22 | #include "base/Error.h" 23 | 24 | #include 25 | #include 26 | 27 | namespace encfs { 28 | 29 | #ifndef MIN 30 | inline int MIN(int a, int b) { return (a < b) ? a : b; } 31 | #endif 32 | 33 | ConfigVar::ConfigVar() : pd(new ConfigVarData) { pd->offset = 0; } 34 | 35 | ConfigVar::ConfigVar(const std::string &buf) : pd(new ConfigVarData) { 36 | pd->buffer = buf; 37 | pd->offset = 0; 38 | } 39 | 40 | ConfigVar::ConfigVar(const ConfigVar &src) { pd = src.pd; } 41 | 42 | ConfigVar::~ConfigVar() { pd.reset(); } 43 | 44 | ConfigVar &ConfigVar::operator=(const ConfigVar &src) { 45 | if (src.pd == pd) 46 | return *this; 47 | else 48 | pd = src.pd; 49 | 50 | return *this; 51 | } 52 | 53 | void ConfigVar::resetOffset() { pd->offset = 0; } 54 | 55 | int ConfigVar::read(byte *buffer_, int bytes) const { 56 | int toCopy = MIN(bytes, pd->buffer.size() - pd->offset); 57 | 58 | if (toCopy > 0) memcpy(buffer_, pd->buffer.data() + pd->offset, toCopy); 59 | 60 | pd->offset += toCopy; 61 | 62 | return toCopy; 63 | } 64 | 65 | int ConfigVar::write(const byte *data, int bytes) { 66 | if (pd->buffer.size() == (unsigned int)pd->offset) { 67 | pd->buffer.append((const char *)data, bytes); 68 | } else { 69 | pd->buffer.insert(pd->offset, (const char *)data, bytes); 70 | } 71 | 72 | pd->offset += bytes; 73 | 74 | return bytes; 75 | } 76 | 77 | int ConfigVar::size() const { return pd->buffer.size(); } 78 | 79 | const char *ConfigVar::buffer() const { return pd->buffer.data(); } 80 | 81 | int ConfigVar::at() const { return pd->offset; } 82 | 83 | void ConfigVar::writeString(const char *data, int bytes) { 84 | writeInt(bytes); 85 | write((const byte *)data, bytes); 86 | } 87 | 88 | // convert integer to BER encoded integer 89 | void ConfigVar::writeInt(int val) { 90 | // we can represent 7 bits per char output, so a 32bit number may take up 91 | // to 5 bytes. 92 | // first byte: 0x0000007f 0111,1111 93 | // second byte: 0x00003f80 0011,1111 1000,0000 94 | // third byte: 0x001fb000 0000,0000 0001,1111 1100,0000 0000,0000 95 | // fourth byte: 0x0fe00000 0000,1111 1110,0000 96 | // fifth byte: 0xf0000000 1111,0000 97 | byte digit[5]; 98 | 99 | digit[4] = (byte)((val & 0x0000007f)); 100 | digit[3] = 0x80 | (byte)((val & 0x00003f80) >> 7); 101 | digit[2] = 0x80 | (byte)((val & 0x001fc000) >> 14); 102 | digit[1] = 0x80 | (byte)((val & 0x0fe00000) >> 21); 103 | digit[0] = 0x80 | (byte)((val & 0xf0000000) >> 28); 104 | 105 | // find the starting point - we only need to output starting at the most 106 | // significant non-zero digit.. 107 | int start = 0; 108 | while (digit[start] == 0x80) ++start; 109 | 110 | write(digit + start, 5 - start); 111 | } 112 | 113 | int ConfigVar::readInt() const { 114 | const byte *buf = (const byte *)buffer(); 115 | int bytes = this->size(); 116 | int offset = at(); 117 | int value = 0; 118 | bool highBitSet; 119 | 120 | rAssert(offset < bytes); 121 | 122 | do { 123 | byte tmp = buf[offset++]; 124 | highBitSet = tmp & 0x80; 125 | 126 | value = (value << 7) | (int)(tmp & 0x7f); 127 | } while (highBitSet && offset < bytes); 128 | 129 | pd->offset = offset; 130 | 131 | // should never end up with a negative number.. 132 | rAssert(value >= 0); 133 | 134 | return value; 135 | } 136 | 137 | int ConfigVar::readInt(int defaultValue) const { 138 | int bytes = this->size(); 139 | int offset = at(); 140 | 141 | if (offset >= bytes) 142 | return defaultValue; 143 | else 144 | return readInt(); 145 | } 146 | 147 | bool ConfigVar::readBool(bool defaultValue) const { 148 | int tmp = readInt(defaultValue ? 1 : 0); 149 | return (tmp != 0); 150 | } 151 | 152 | ConfigVar &operator<<(ConfigVar &src, bool value) { 153 | src.writeInt(value ? 1 : 0); 154 | return src; 155 | } 156 | 157 | ConfigVar &operator<<(ConfigVar &src, int var) { 158 | src.writeInt(var); 159 | return src; 160 | } 161 | 162 | ConfigVar &operator<<(ConfigVar &src, const std::string &str) { 163 | src.writeString(str.data(), str.length()); 164 | return src; 165 | } 166 | 167 | const ConfigVar &operator>>(const ConfigVar &src, bool &result) { 168 | int tmp = src.readInt(); 169 | result = (tmp != 0); 170 | return src; 171 | } 172 | 173 | const ConfigVar &operator>>(const ConfigVar &src, int &result) { 174 | result = src.readInt(); 175 | return src; 176 | } 177 | 178 | const ConfigVar &operator>>(const ConfigVar &src, std::string &result) { 179 | int length = src.readInt(); 180 | LOG_IF(WARNING, length <= 0) << "Invalid config length " << length; 181 | 182 | int readLen; 183 | 184 | byte tmpBuf[32]; 185 | if (length > (int)sizeof(tmpBuf)) { 186 | byte *ptr = new byte[length]; 187 | readLen = src.read(ptr, length); 188 | result.assign((char *)ptr, length); 189 | delete[] ptr; 190 | } else { 191 | readLen = src.read(tmpBuf, length); 192 | result.assign((char *)tmpBuf, length); 193 | } 194 | 195 | if (readLen != length) { 196 | VLOG(1) << "string encoded as size " << length << " bytes, read " 197 | << readLen; 198 | } 199 | 200 | rAssert(readLen == length); 201 | 202 | return src; 203 | } 204 | 205 | } // namespace encfs 206 | -------------------------------------------------------------------------------- /cipher/readpassphrase.cpp: -------------------------------------------------------------------------------- 1 | /* $OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $ 2 | */ 3 | 4 | /* 5 | * Copyright (c) 2000 Todd C. Miller 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 3. The name of the author may not be used to endorse or promote products 17 | * derived from this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 21 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 25 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 27 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 28 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #if defined(LIBC_SCCS) && !defined(lint) 32 | static const char rcsid[] = 33 | "$OpenBSD: readpassphrase.c,v 1.12 2001/12/15 05:41:00 millert Exp $"; 34 | #endif /* LIBC_SCCS and not lint */ 35 | 36 | //#include "includes.h" 37 | 38 | #ifndef HAVE_READPASSPHRASE 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | #include 52 | #include "cipher/readpassphrase.h" 53 | 54 | #ifdef TCSASOFT 55 | #define _T_FLUSH (TCSAFLUSH | TCSASOFT) 56 | #else 57 | #define _T_FLUSH (TCSAFLUSH) 58 | #endif 59 | 60 | /* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ 61 | #if !defined(_POSIX_VDISABLE) && defined(VDISABLE) 62 | #define _POSIX_VDISABLE VDISABLE 63 | #endif 64 | 65 | static volatile sig_atomic_t signo; 66 | 67 | static void handler(int); 68 | 69 | char *readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) { 70 | ssize_t nr; 71 | int input, output, save_errno; 72 | char ch, *p, *end; 73 | struct termios term, oterm; 74 | struct sigaction sa, saveint, savehup, savequit, saveterm; 75 | struct sigaction savetstp, savettin, savettou; 76 | 77 | /* I suppose we could alloc on demand in this case (XXX). */ 78 | if (bufsiz == 0) { 79 | errno = EINVAL; 80 | return (NULL); 81 | } 82 | 83 | restart: 84 | /* 85 | * Read and write to /dev/tty if available. If not, read from 86 | * stdin and write to stderr unless a tty is required. 87 | */ 88 | if ((input = output = open(_PATH_TTY, O_RDWR)) == -1) { 89 | if (flags & RPP_REQUIRE_TTY) { 90 | errno = ENOTTY; 91 | return (NULL); 92 | } 93 | input = STDIN_FILENO; 94 | output = STDERR_FILENO; 95 | } 96 | 97 | /* 98 | * Catch signals that would otherwise cause the user to end 99 | * up with echo turned off in the shell. Don't worry about 100 | * things like SIGALRM and SIGPIPE for now. 101 | */ 102 | sigemptyset(&sa.sa_mask); 103 | sa.sa_flags = 0; /* don't restart system calls */ 104 | sa.sa_handler = handler; 105 | (void)sigaction(SIGINT, &sa, &saveint); 106 | (void)sigaction(SIGHUP, &sa, &savehup); 107 | (void)sigaction(SIGQUIT, &sa, &savequit); 108 | (void)sigaction(SIGTERM, &sa, &saveterm); 109 | (void)sigaction(SIGTSTP, &sa, &savetstp); 110 | (void)sigaction(SIGTTIN, &sa, &savettin); 111 | (void)sigaction(SIGTTOU, &sa, &savettou); 112 | 113 | /* Turn off echo if possible. */ 114 | if (tcgetattr(input, &oterm) == 0) { 115 | memcpy(&term, &oterm, sizeof(term)); 116 | if (!(flags & RPP_ECHO_ON)) term.c_lflag &= ~(ECHO | ECHONL); 117 | #ifdef VSTATUS 118 | if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) 119 | term.c_cc[VSTATUS] = _POSIX_VDISABLE; 120 | #endif 121 | (void)tcsetattr(input, _T_FLUSH, &term); 122 | } else { 123 | memset(&term, 0, sizeof(term)); 124 | memset(&oterm, 0, sizeof(oterm)); 125 | } 126 | 127 | (void)write(output, prompt, strlen(prompt)); 128 | end = buf + bufsiz - 1; 129 | for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { 130 | if (p < end) { 131 | if ((flags & RPP_SEVENBIT)) ch &= 0x7f; 132 | if (isalpha(ch)) { 133 | if ((flags & RPP_FORCELOWER)) ch = tolower(ch); 134 | if ((flags & RPP_FORCEUPPER)) ch = toupper(ch); 135 | } 136 | *p++ = ch; 137 | } 138 | } 139 | *p = '\0'; 140 | save_errno = errno; 141 | if (!(term.c_lflag & ECHO)) (void)write(output, "\n", 1); 142 | 143 | /* Restore old terminal settings and signals. */ 144 | if (memcmp(&term, &oterm, sizeof(term)) != 0) 145 | (void)tcsetattr(input, _T_FLUSH, &oterm); 146 | (void)sigaction(SIGINT, &saveint, NULL); 147 | (void)sigaction(SIGHUP, &savehup, NULL); 148 | (void)sigaction(SIGQUIT, &savequit, NULL); 149 | (void)sigaction(SIGTERM, &saveterm, NULL); 150 | (void)sigaction(SIGTSTP, &savetstp, NULL); 151 | (void)sigaction(SIGTTIN, &savettin, NULL); 152 | (void)sigaction(SIGTTOU, &savettou, NULL); 153 | if (input != STDIN_FILENO) (void)close(input); 154 | 155 | /* 156 | * If we were interrupted by a signal, resend it to ourselves 157 | * now that we have restored the signal handlers. 158 | */ 159 | if (signo) { 160 | kill(getpid(), signo); 161 | switch (signo) { 162 | case SIGTSTP: 163 | case SIGTTIN: 164 | case SIGTTOU: 165 | signo = 0; 166 | goto restart; 167 | } 168 | } 169 | 170 | errno = save_errno; 171 | return (nr == -1 ? NULL : buf); 172 | } 173 | #endif /* HAVE_READPASSPHRASE */ 174 | 175 | #if 0 176 | char * 177 | getpass(const char *prompt) 178 | { 179 | static char buf[_PASSWORD_LEN + 1]; 180 | 181 | return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); 182 | } 183 | #endif 184 | 185 | static void handler(int s) { signo = s; } 186 | -------------------------------------------------------------------------------- /fs/StreamNameIO.cpp: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * Author: Valient Gough 3 | * 4 | ***************************************************************************** 5 | * Copyright (c) 2004, Valient Gough 6 | * 7 | * This program is free software: you can redistribute it and/or modify it 8 | * under the terms of the GNU Lesser General Public License as published by the 9 | * Free Software Foundation, either version 3 of the License, or (at your 10 | * option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 15 | * for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this program. If not, see . 19 | */ 20 | 21 | #include "base/base64.h" 22 | #include "base/Error.h" 23 | #include "base/i18n.h" 24 | #include "cipher/CipherV1.h" 25 | #include "fs/StreamNameIO.h" 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | namespace encfs { 34 | 35 | using std::string; 36 | using std::vector; 37 | 38 | static shared_ptr NewStreamNameIO(const Interface &iface, 39 | const shared_ptr &cipher) { 40 | return shared_ptr(new StreamNameIO(iface, cipher)); 41 | } 42 | 43 | static bool StreamIO_registered = NameIO::Register( 44 | "Stream", 45 | gettext_noop("Stream encoding, keeps filenames as short as possible"), 46 | StreamNameIO::CurrentInterface(), NewStreamNameIO, true); 47 | 48 | /* 49 | - Version 0.1 is for EncFS 0.x support. The difference to 1.0 is that 0.x 50 | stores the file checksums at the end of the encoded name, where 1.0 51 | stores them at the beginning. 52 | 53 | - Version 1.0 is the basic stream encoding mode used since the beginning of 54 | EncFS. There is a slight difference in filename encodings from EncFS 0.x 55 | to 1.0.x. This implements just the 1.0.x method. 56 | 57 | - Version 1.1 adds support for IV chaining. This is transparently 58 | backward compatible, since older filesystems do not use IV chaining. 59 | 60 | - Version 2.0 uses full 64 bit IV during IV chaining mode. Prior versions 61 | used only the 16 bit output from MAC_16. This reduces the theoretical 62 | possibility (unlikely to make any difference in practice) of two files 63 | with the same name in different directories ending up with the same 64 | encrypted name. Added because there is no good reason to chop to 16 65 | bits. 66 | 67 | - Version 2.1 adds support for version 0 for EncFS 0.x compatibility. 68 | 69 | - Version 3.0 drops Encfs 0.x support. 70 | */ 71 | Interface StreamNameIO::CurrentInterface() { 72 | // implements support for version 3, 2, and 1. 73 | return makeInterface("nameio/stream", 3, 0, 2); 74 | } 75 | 76 | StreamNameIO::StreamNameIO(const Interface &iface, 77 | const shared_ptr &cipher) 78 | : _interface(iface.major()), _cipher(cipher) {} 79 | 80 | StreamNameIO::~StreamNameIO() {} 81 | 82 | Interface StreamNameIO::interface() const { return CurrentInterface(); } 83 | 84 | int StreamNameIO::maxEncodedNameLen(int plaintextStreamLen) const { 85 | int encodedStreamLen = 2 + plaintextStreamLen; 86 | return B256ToB64Bytes(encodedStreamLen); 87 | } 88 | 89 | int StreamNameIO::maxDecodedNameLen(int encodedStreamLen) const { 90 | int decLen256 = B64ToB256Bytes(encodedStreamLen); 91 | return decLen256 - 2; 92 | } 93 | 94 | string StreamNameIO::encodeName(const string &plaintextName, 95 | uint64_t *iv) const { 96 | uint64_t tmpIV = 0; 97 | int length = plaintextName.length(); 98 | if (iv && _interface >= 2) tmpIV = *iv; 99 | 100 | unsigned int mac = _cipher->reduceMac16(_cipher->MAC_64( 101 | reinterpret_cast(plaintextName.data()), length, iv)); 102 | tmpIV ^= (uint64_t)mac; 103 | 104 | int encodedStreamLen = length + 2; 105 | int encLen64 = B256ToB64Bytes(encodedStreamLen); 106 | 107 | // add on checksum bytes 108 | vector encoded(encLen64); 109 | encoded[0] = static_cast((mac >> 8) & 0xff); 110 | encoded[1] = static_cast((mac) & 0xff); 111 | 112 | // stream encode the plaintext bytes 113 | memcpy(&encoded[2], plaintextName.data(), length); 114 | _cipher->streamEncode(&encoded[2], length, tmpIV); 115 | 116 | // convert the entire thing to base 64 ascii.. 117 | changeBase2Inline(encoded.data(), encodedStreamLen, 8, 6, true); 118 | B64ToAscii(encoded.data(), encLen64); 119 | 120 | return string(encoded.begin(), encoded.end()); 121 | } 122 | 123 | string StreamNameIO::decodeName(const string &encodedName, 124 | uint64_t *iv) const { 125 | int length = encodedName.length(); 126 | rAssert(length > 2); 127 | int decLen256 = B64ToB256Bytes(length); 128 | int decodedStreamLen = decLen256 - 2; 129 | 130 | if (decodedStreamLen <= 0) throw Error("Filename too small to decode"); 131 | 132 | vector tmpBuf(length, 0); 133 | 134 | // decode into tmpBuf, because this step produces more data then we can fit 135 | // into the result buffer.. 136 | memcpy(tmpBuf.data(), encodedName.data(), length); 137 | AsciiToB64(tmpBuf.data(), length); 138 | changeBase2Inline(tmpBuf.data(), length, 6, 8, false); 139 | 140 | // pull out the checksum value which is used as an initialization vector 141 | uint64_t tmpIV = 0; 142 | unsigned int mac = ((unsigned int)tmpBuf[0]) << 8 | ((unsigned int)tmpBuf[1]); 143 | 144 | // version 2 adds support for IV chaining.. 145 | if (iv && _interface >= 2) tmpIV = *iv; 146 | 147 | tmpIV ^= (uint64_t)mac; 148 | _cipher->streamDecode(&tmpBuf.at(2), decodedStreamLen, tmpIV); 149 | 150 | // compute MAC to check with stored value 151 | unsigned int mac2 = _cipher->reduceMac16( 152 | _cipher->MAC_64(&tmpBuf.at(2), decodedStreamLen, iv)); 153 | 154 | if (mac2 != mac) { 155 | VLOG(1) << "checksum mismatch: expected " << mac << ", got " << mac2 156 | << "on decode of " << decodedStreamLen << " bytes"; 157 | throw Error("checksum mismatch in filename decode"); 158 | } 159 | 160 | return string(reinterpret_cast(&tmpBuf.at(2)), decodedStreamLen); 161 | } 162 | 163 | bool StreamNameIO::Enabled() { return true; } 164 | 165 | } // namespace encfs 166 | -------------------------------------------------------------------------------- /fs/testing.cpp: -------------------------------------------------------------------------------- 1 | 2 | /***************************************************************************** 3 | * Author: Valient Gough 4 | * 5 | ***************************************************************************** 6 | * Copyright (c) 2012 Valient Gough 7 | * 8 | * This program is free software: you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License as published by the Free 10 | * Software Foundation, either version 3 of the License, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but WITHOUT 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 16 | * details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public License 19 | * along with this program. If not, see . 20 | */ 21 | 22 | #include "fs/testing.h" 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include "cipher/CipherV1.h" 31 | #include "cipher/MemoryPool.h" 32 | 33 | #include "fs/FSConfig.h" 34 | #include "fs/fsconfig.pb.h" 35 | #include "fs/FileUtils.h" 36 | #include "fs/MACFileIO.h" 37 | #include "fs/MemFileIO.h" 38 | 39 | using std::list; 40 | using std::string; 41 | 42 | namespace encfs { 43 | 44 | FSConfigPtr makeConfig(const shared_ptr& cipher, int blockSize) { 45 | FSConfigPtr cfg = FSConfigPtr(new FSConfig); 46 | cfg->cipher = cipher; 47 | cfg->key = cipher->newRandomKey(); 48 | cfg->cipher->setKey(cfg->key); 49 | cfg->config.reset(new EncfsConfig); 50 | cfg->config->set_block_size(blockSize); 51 | cfg->opts.reset(new EncFS_Opts); 52 | 53 | return cfg; 54 | } 55 | 56 | void runWithCipher(const string& cipherName, int blockSize, 57 | void (*func)(FSConfigPtr& config)) { 58 | shared_ptr cipher = CipherV1::New(cipherName); 59 | ASSERT_TRUE(cipher.get() != NULL); 60 | 61 | FSConfigPtr cfg = makeConfig(cipher, blockSize); 62 | ASSERT_NO_FATAL_FAILURE(func(cfg)); 63 | } 64 | 65 | void runWithAllCiphers(void (*func)(FSConfigPtr& config)) { 66 | list algorithms = CipherV1::GetAlgorithmList(); 67 | list::const_iterator it; 68 | for (it = algorithms.begin(); it != algorithms.end(); ++it) { 69 | int blockSize = it->blockSize.closest(512); 70 | int keyLength = it->keyLength.closest(128); 71 | SCOPED_TRACE(testing::Message() << "Testng with cipher " << it->name 72 | << ", blocksize " << blockSize 73 | << ", keyLength " << keyLength); 74 | shared_ptr cipher = CipherV1::New(it->iface, keyLength); 75 | ASSERT_TRUE(cipher.get() != NULL); 76 | 77 | FSConfigPtr cfg = makeConfig(cipher, blockSize); 78 | ASSERT_NO_FATAL_FAILURE(func(cfg)); 79 | } 80 | } 81 | 82 | void truncate(FileIO* a, FileIO* b, int len) { 83 | SCOPED_TRACE(testing::Message() << "Truncate from " << a->getSize() 84 | << " to len " << len); 85 | a->truncate(len); 86 | ASSERT_EQ(len, a->getSize()); 87 | 88 | b->truncate(len); 89 | ASSERT_EQ(len, b->getSize()); 90 | 91 | compare(a, b, 0, len); 92 | } 93 | 94 | void writeRandom(FSConfigPtr& cfg, FileIO* a, FileIO* b, int offset, int len) { 95 | SCOPED_TRACE(testing::Message() << "Write random " << offset << ", " << len); 96 | 97 | if (a->getSize() < offset + len) { 98 | a->truncate(offset + len); 99 | } 100 | 101 | if (b->getSize() < offset + len) { 102 | b->truncate(offset + len); 103 | } 104 | 105 | unsigned char* buf = new unsigned char[len]; 106 | ASSERT_TRUE(cfg->cipher->pseudoRandomize(buf, len)); 107 | 108 | IORequest req; 109 | req.data = new unsigned char[len]; 110 | req.dataLen = len; 111 | 112 | memcpy(req.data, buf, len); 113 | req.offset = offset; 114 | ASSERT_TRUE(a->write(req)); 115 | 116 | // Check that write succeeded. 117 | req.offset = offset; 118 | req.dataLen = len; 119 | ASSERT_EQ(len, a->read(req)); 120 | ASSERT_TRUE(memcmp(req.data, buf, len) == 0); 121 | 122 | memcpy(req.data, buf, len); 123 | req.offset = offset; 124 | req.dataLen = len; 125 | ASSERT_TRUE(b->write(req)); 126 | 127 | // Check that write succeeded. 128 | req.offset = offset; 129 | req.dataLen = len; 130 | ASSERT_EQ(len, b->read(req)); 131 | ASSERT_TRUE(memcmp(req.data, buf, len) == 0); 132 | 133 | compare(a, b, offset, len); 134 | 135 | delete[] buf; 136 | delete[] req.data; 137 | } 138 | 139 | void compare(FileIO* a, FileIO* b, int offset, int len) { 140 | SCOPED_TRACE(testing::Message() << "compare " << offset << ", " << len 141 | << " from file length " << a->getSize()); 142 | unsigned char* buf1 = new unsigned char[len]; 143 | unsigned char* buf2 = new unsigned char[len]; 144 | memset(buf1, 0, len); 145 | memset(buf2, 0, len); 146 | 147 | IORequest req; 148 | req.offset = offset; 149 | req.data = buf1; 150 | req.dataLen = len; 151 | ssize_t size1 = a->read(req); 152 | 153 | req.offset = offset; 154 | req.data = buf2; 155 | req.dataLen = len; 156 | ssize_t size2 = b->read(req); 157 | 158 | ASSERT_EQ(size1, size2); 159 | for (int i = 0; i < len; i++) { 160 | bool match = (buf1[i] == buf2[i]); 161 | ASSERT_TRUE(match) << "mismatched data at offset " << i << " of " << len 162 | << ", got " << int(buf1[i]) << " and " << int(buf2[i]); 163 | if (!match) { 164 | break; 165 | } 166 | } 167 | 168 | delete[] buf1; 169 | delete[] buf2; 170 | } 171 | 172 | void comparisonTest(FSConfigPtr& cfg, FileIO* a, FileIO* b) { 173 | const int size = 2 * 1024; 174 | writeRandom(cfg, a, b, 0, size); 175 | if (testing::Test::HasFatalFailure()) return; 176 | 177 | for (int i = 0; i < 10000; i++) { 178 | SCOPED_TRACE(testing::Message() << "Test Loop " << i); 179 | int len = 128 + random() % 512; 180 | int offset = (len == a->getSize()) ? 0 : random() % (a->getSize() - len); 181 | writeRandom(cfg, a, b, offset, len); 182 | if (testing::Test::HasFatalFailure()) return; 183 | ASSERT_EQ(a->getSize(), b->getSize()); 184 | } 185 | 186 | SCOPED_TRACE("Final Compare"); 187 | compare(a, b, 0, a->getSize()); 188 | } 189 | 190 | int main(int argc, char** argv) { 191 | ::testing::InitGoogleTest(&argc, argv); 192 | google::InitGoogleLogging(argv[0]); 193 | 194 | return RUN_ALL_TESTS(); 195 | } 196 | 197 | } // namespace encfs 198 | --------------------------------------------------------------------------------