2015-06-16 18:20:31 +02:00
# include "CryConfigLoader.h"
2015-10-19 02:46:47 +02:00
# include "CryConfigFile.h"
2015-06-16 18:20:31 +02:00
# include <boost/filesystem.hpp>
2016-02-11 16:39:42 +01:00
# include <cpp-utils/random/Random.h>
# include <cpp-utils/logging/logging.h>
2016-02-09 10:55:28 +01:00
# include <boost/algorithm/string/predicate.hpp>
2016-03-02 13:53:37 +01:00
# include <gitversion/gitversion.h>
2016-03-26 16:53:08 +01:00
# include <gitversion/VersionCompare.h>
2015-06-16 18:20:31 +02:00
namespace bf = boost : : filesystem ;
2015-06-18 13:45:08 +02:00
using cpputils : : unique_ref ;
using cpputils : : make_unique_ref ;
2015-09-12 20:16:13 +02:00
using cpputils : : Console ;
using cpputils : : IOStreamConsole ;
2015-10-24 19:35:37 +02:00
using cpputils : : Random ;
using cpputils : : RandomGenerator ;
2015-11-04 05:27:00 +01:00
using cpputils : : SCryptSettings ;
2015-06-18 13:45:08 +02:00
using boost : : optional ;
using boost : : none ;
2016-01-17 14:57:40 +01:00
using std : : shared_ptr ;
2015-07-01 14:33:18 +02:00
using std : : vector ;
using std : : string ;
2015-10-24 19:35:37 +02:00
using std : : function ;
2015-11-04 05:27:00 +01:00
using std : : shared_ptr ;
2016-03-26 16:53:08 +01:00
using gitversion : : VersionCompare ;
2015-10-26 16:36:57 +01:00
using namespace cpputils : : logging ;
2015-06-16 18:20:31 +02:00
namespace cryfs {
2016-03-04 23:12:41 +01:00
CryConfigLoader : : CryConfigLoader ( shared_ptr < Console > console , RandomGenerator & keyGenerator , const SCryptSettings & scryptSettings , function < string ( ) > askPasswordForExistingFilesystem , function < string ( ) > askPasswordForNewFilesystem , const optional < string > & cipherFromCommandLine , const boost : : optional < uint32_t > & blocksizeBytesFromCommandLine , bool noninteractive )
2016-02-21 01:34:21 +01:00
: _creator ( std : : move ( console ) , keyGenerator , noninteractive ) , _scryptSettings ( scryptSettings ) ,
2015-11-19 10:08:09 +01:00
_askPasswordForExistingFilesystem ( askPasswordForExistingFilesystem ) , _askPasswordForNewFilesystem ( askPasswordForNewFilesystem ) ,
2016-03-04 23:12:41 +01:00
_cipherFromCommandLine ( cipherFromCommandLine ) , _blocksizeBytesFromCommandLine ( blocksizeBytesFromCommandLine ) {
2015-10-24 19:35:37 +02:00
}
2015-07-26 13:09:55 +02:00
2015-10-26 16:36:57 +01:00
optional < CryConfigFile > CryConfigLoader : : _loadConfig ( const bf : : path & filename ) {
2015-11-19 10:08:09 +01:00
string password = _askPasswordForExistingFilesystem ( ) ;
2016-02-16 20:35:51 +01:00
std : : cout < < " Loading config file (this can take some time)... " < < std : : flush ;
2015-10-24 19:35:37 +02:00
auto config = CryConfigFile : : load ( filename , password ) ;
if ( config = = none ) {
2015-10-26 16:36:57 +01:00
return none ;
2015-06-16 18:20:31 +02:00
}
2015-11-19 10:08:09 +01:00
std : : cout < < " done " < < std : : endl ;
2016-02-09 10:55:28 +01:00
_checkVersion ( * config - > config ( ) ) ;
2016-03-26 16:53:08 +01:00
# ifndef CRYFS_NO_COMPATIBILITY
//Since 0.9.3-alpha set the config value cryfs.blocksizeBytes wrongly to 32768 (but didn't use the value), we have to fix this here.
if ( config - > config ( ) - > Version ( ) ! = " 0+unknown " & & VersionCompare : : isOlderThan ( config - > config ( ) - > Version ( ) , " 0.9.3-rc1 " ) ) {
config - > config ( ) - > SetBlocksizeBytes ( 32832 ) ;
}
# endif
2016-03-26 17:09:07 +01:00
if ( config - > config ( ) - > Version ( ) ! = gitversion : : VersionString ( ) ) {
config - > config ( ) - > SetVersion ( gitversion : : VersionString ( ) ) ;
config - > save ( ) ;
}
2016-02-09 10:55:28 +01:00
_checkCipher ( * config - > config ( ) ) ;
2015-10-24 19:35:37 +02:00
return std : : move ( * config ) ;
}
2016-02-09 10:55:28 +01:00
void CryConfigLoader : : _checkVersion ( const CryConfig & config ) {
2016-03-02 13:53:37 +01:00
const string allowedVersionPrefix = string ( ) + gitversion : : MajorVersion ( ) + " . " + gitversion : : MinorVersion ( ) + " . " ;
2016-02-09 10:55:28 +01:00
if ( ! boost : : starts_with ( config . Version ( ) , allowedVersionPrefix ) ) {
throw std : : runtime_error ( string ( ) + " This filesystem was created with CryFS " + config . Version ( ) + " and is incompatible. Please create a new one with your version of CryFS and migrate your data. " ) ;
}
}
void CryConfigLoader : : _checkCipher ( const CryConfig & config ) const {
if ( _cipherFromCommandLine ! = none & & config . Cipher ( ) ! = * _cipherFromCommandLine ) {
throw std : : runtime_error ( string ( ) + " Filesystem uses " + config . Cipher ( ) + " cipher and not " + * _cipherFromCommandLine + " as specified. " ) ;
}
}
2015-11-04 05:27:00 +01:00
optional < CryConfigFile > CryConfigLoader : : loadOrCreate ( const bf : : path & filename ) {
if ( bf : : exists ( filename ) ) {
return _loadConfig ( filename ) ;
} else {
return _createConfig ( filename ) ;
}
}
CryConfigFile CryConfigLoader : : _createConfig ( const bf : : path & filename ) {
2016-03-04 23:12:41 +01:00
auto config = _creator . create ( _cipherFromCommandLine , _blocksizeBytesFromCommandLine ) ;
2015-11-04 05:27:00 +01:00
//TODO Ask confirmation if using insecure password (<8 characters)
2015-11-19 10:08:09 +01:00
string password = _askPasswordForNewFilesystem ( ) ;
2016-02-16 20:35:51 +01:00
std : : cout < < " Creating config file (this can take some time)... " < < std : : flush ;
2015-11-19 10:08:09 +01:00
auto result = CryConfigFile : : create ( filename , std : : move ( config ) , password , _scryptSettings ) ;
std : : cout < < " done " < < std : : endl ;
return result ;
2015-11-04 05:27:00 +01:00
}
2015-06-16 18:20:31 +02:00
}