diff --git a/configure.ac b/configure.ac index d7a4978..b35d6f2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(encfs/encfs.h) dnl a source file from your sub dir -AM_INIT_AUTOMAKE(encfs, 1.4.0) dnl searches for some needed programs +AM_INIT_AUTOMAKE(encfs, 1.4.1) dnl searches for some needed programs dnl without this order in this file, automake will be confused! dnl diff --git a/encfs/FileUtils.cpp b/encfs/FileUtils.cpp index 249b7e6..c5e66c5 100644 --- a/encfs/FileUtils.cpp +++ b/encfs/FileUtils.cpp @@ -63,6 +63,10 @@ using namespace std; using namespace gnu; static const int DefaultBlockSize = 512; +// The maximum length of text passwords. If longer are needed, +// use the extpass option, as extpass can return arbitrary length binary data. +static const int MaxPassBuf = 512; + // environment variable names for values encfs stores in the environment when // calling an external password program. static const char ENCFS_ENV_ROOTDIR[] = "encfs_root"; @@ -1146,13 +1150,15 @@ void showFSInfo( const EncFSConfig &config ) CipherKey getUserKey( const shared_ptr &cipher, bool useStdin ) { - const int MaxPassBuf = 1024; char passBuf[MaxPassBuf]; char *res; if( useStdin ) { res = fgets( passBuf, sizeof(passBuf), stdin ); + // Kill the trailing newline. + if(passBuf[ strlen(passBuf)-1 ] == '\n') + passBuf[ strlen(passBuf)-1 ] = '\0'; } else { // xgroup(common) @@ -1173,7 +1179,7 @@ CipherKey getUserKey( const shared_ptr &cipher, bool useStdin ) std::string readPassword( int FD ) { - char buffer[2048]; + char buffer[1024]; string result; while(1) @@ -1279,7 +1285,6 @@ CipherKey getUserKey( const std::string &passProg, CipherKey getNewUserKey( const shared_ptr &cipher ) { - const int MaxPassBuf = 64; CipherKey userKey; char passBuf[MaxPassBuf]; char passBuf2[MaxPassBuf]; diff --git a/encfs/MemoryPool.cpp b/encfs/MemoryPool.cpp index 0421f35..2731a6e 100644 --- a/encfs/MemoryPool.cpp +++ b/encfs/MemoryPool.cpp @@ -34,41 +34,33 @@ using namespace rlog; -#if HAVE_SSL - # include #define BLOCKDATA( BLOCK ) (unsigned char*)BLOCK->data->data -#endif - struct BlockList { BlockList *next; int size; -#ifdef HAVE_SSL BUF_MEM *data; -#endif }; static BlockList *allocBlock( int size ) { BlockList *block = new BlockList; block->size = size; -#ifdef HAVE_SSL block->data = BUF_MEM_new( ); BUF_MEM_grow( block->data, size ); VALGRIND_MAKE_MEM_NOACCESS( block->data->data, block->data->max ); -#endif + return block; } static void freeBlock( BlockList *el ) { -#ifdef HAVE_SSL VALGRIND_MAKE_MEM_UNDEFINED( el->data->data, el->data->max ); BUF_MEM_free( el->data ); -#endif + delete el; } diff --git a/encfs/encfs.cpp b/encfs/encfs.cpp index 6e4e5c8..d0e8622 100644 --- a/encfs/encfs.cpp +++ b/encfs/encfs.cpp @@ -48,6 +48,7 @@ extern "C" { #include #include +#include #include "DirNode.h" #include "MemoryPool.h" @@ -161,7 +162,28 @@ static int withFileNode( const char *opName, int _do_getattr(FileNode *fnode, struct stat *stbuf) { - return fnode->getAttr(stbuf); + int res = fnode->getAttr(stbuf); + if(res == ESUCCESS && S_ISLNK(stbuf->st_mode)) + { + EncFS_Context *ctx = context(); + shared_ptr FSRoot = ctx->getRoot(&res); + if(FSRoot) + { + // determine plaintext link size.. Easiest to read and decrypt.. + scoped_array buf(new char[stbuf->st_size+1]); + + res = ::readlink( fnode->cipherName(), buf.get(), stbuf->st_size ); + // other functions expect c-strings to be null-terminated, which + // readlink doesn't provide + buf[res] = '\0'; + + stbuf->st_size = FSRoot->plainPath( buf.get() ).length(); + + res = ESUCCESS; + } + } + + return res; } int encfs_getattr(const char *path, struct stat *stbuf) @@ -339,7 +361,6 @@ int encfs_rmdir(const char *path) return withCipherPath( "rmdir", path, _do_rmdir, 0 ); } - int _do_readlink(EncFS_Context *ctx, const string &cyName, tuple data ) { diff --git a/encfs/encfs.pod b/encfs/encfs.pod index f3b7c95..8d3203c 100644 --- a/encfs/encfs.pod +++ b/encfs/encfs.pod @@ -1,10 +1,10 @@ =cut -Copyright (c) 2003-2004, Valient Gough +Copyright (c) 2003-2008, Valient Gough All rights reserved. EncFS is free software; you can distribute it and/or modify it under the terms of the GNU General Public License (GPL), as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later +Foundation; either version 3 of the License, or (at your option) any later version. =pod @@ -19,17 +19,18 @@ B [B<--version>] [B<-s>] [B<-f>] [B<-v>|B<--verbose>] [B<-i MINUTES>|B<--idle=MINUTES>] [B<--extpass=program>] [B<-S>|B<--stdinpass>] [B<--anykey>] [B<--forcedecode>] [B<-d>|B<--fuse-debug>] [B<--public>] [B<--no-default-flags>] +[B<--ondemand>] [B<--reverse>] [B<-o FUSE_OPTION>] I I [B<--> [I]] =head1 DESCRIPTION -B creates a virtual encrypted filesystem which stores encrypted data in +B creates a virtual encrypted filesystem which stores encrypted data in the I directory and makes the unencrypted data visible at the I directory. The user must supply a password which is used to (indirectly) encrypt both filenames and file contents. -If B is unable to find a supported filesystem at the specified +If B is unable to find a supported filesystem at the specified I, then the user will be asked if they wish to create a new encrypted filesystem at the specified location. Options will be presented to the user allowing some control over the algorithms to use. As B matures, there @@ -49,8 +50,8 @@ However simply having files open does not count as activity. =item B<-f> -The B<-f> (I) option causes B to run in the foreground. -Normally B spawns off as a daemon and runs in the background, returning +The B<-f> (I) option causes B to run in the foreground. +Normally B spawns off as a daemon and runs in the background, returning control to the spawning shell. With the B<-f> option, it will run in the foreground and any warning/debug log messages will be displayed on standard error. In the default (background) mode, all log messages are logged via @@ -58,25 +59,25 @@ syslog. =item B<-v>, B<--verbose> -Causes B to enable logging of various debug channels within B. +Causes B to enable logging of various debug channels within B. Normally these logging messages are disabled and have no effect. It is recommended that you run in foreground (B<-f>) mode when running with verbose enabled. =item B<-s> -The B<-s> (I) option causes B to run in single threaded -mode. By default, B runs in multi-threaded mode. This option is used -during B development in order to simplify debugging and allow it to run +The B<-s> (I) option causes B to run in single threaded +mode. By default, B runs in multi-threaded mode. This option is used +during B development in order to simplify debugging and allow it to run under memory checking tools.. =item B<-d>, B<--fuse-debug> Enables debugging within the B library. This should only be used if you -suspect a problem within B itself (not B), as it generates a lot +suspect a problem within B itself (not B), as it generates a lot of low-level data and is not likely to be very helpful in general problem tracking. Try I mode (B<-v>) first, which gives a higher level view -of what is happening within B. +of what is happening within B. =item B<--forcedecode> @@ -104,9 +105,59 @@ it will not have the ability to change ownership of files. I recommend that you instead investigate if the fuse allow_other option can be used to do what you want before considering the use of B<--public>. +=item B<--ondemand> + +Mount the filesystem on-demand. This currently only makes sense in combination +with B<--idle> and B<--extpass> options. When the filesystem becomes idle, +instead of exiting, B stops allowing access to the filesystem by +internally dropping it's reference to it. If someone attempts to access the +filesystem again, the extpass program is used to prompt the user for the +password. If this succeeds, then the filesystem becomes available again. + +=item B<--reverse> + +Normally B provides a plaintext view of data on demand. Normally it +stores enciphered data and displays plaintext data. With B<--reverse> it takes +as source plaintext data and produces enciphered data on-demand. This can be +useful for creating remote encrypted backups, where you do not wish to keep the +local files unencrypted. + +For example, the following would create an encrypted view in /tmp/crypt-view. + + encfs --reverse /home/me /tmp/crypt-view + +You could then copy the /tmp/crypt-view directory in order to have a copy of +the encrypted data. You must also keep a copy of the file /home/me/.encfs5 +which contains the filesystem information. Together, the two can be used to +reproduce the unencrypted data: + + ENCFS5_CONFIG=/home/me/.encfs5 encfs /tmp/crypt-view /tmp/plain-view + +Now /tmp/plain-view contains the same data as /home/me + +Note that B<--reverse> mode only works with limited configuration options, so +many settings may be disabled when used. + +=item B<-o FUSE_ARG> + +Pass through B args to the underlying library. This makes it easy to +pass FUSE options when mounting B via mount (and /etc/fstab). Eg: + + mount encfs#/home/me-crypt /home/me -t fuse -o kernel_cache + +Note that encfs arguments cannot be set this way. If you need to set encfs +arguments, create a wrapper, such as encfs-reverse; + + #!/bin/sh + encfs --reverse $* + +Then mount using the script path + + mount encfs-reverse#/home/me /home/me-crypt -t fuse + =item B<--> -The B<--> option tells B to send any remaining arguments directly to +The B<--> option tells B to send any remaining arguments directly to B. In turn, B passes the arguments to B. See the B help page for information on available commands. @@ -135,6 +186,10 @@ for a trailing newline (\n) which will be removed. For example, specifying B<--extpass>=I will cause B to use ssh's password prompt program. +B: B reads at most 2k of data from the password program, and it +removes any trailing newline. Versions before 1.4.x accepted only 64 bytes of +text. + =item B<-S>, B<--stdinpass> Read password from standard input, without prompting. This may be useful for @@ -452,7 +507,7 @@ Per-File Initialization Vector support prevents this. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Please refer to the "COPYING" file distributed with -B for complete details. +B for complete details. =head1 AUTHORS