Change to insert or replace PasswordRAMStore::store() interface (#795617)

Replace the insert() method (which reports an error when inserting a
password with a key which already exists) with the store() method which
replaces or inserts the password depending on whether the key already
exists or not respectively.  There is also an optimisation that nothing
is changed if the password to be replaced is the same as the one already
stored.  The code in Win_GParted::open_encrypted_partition() is
simplified now it doesn't have to implement this pattern of behaviour
itself.

Bug 795617 - Implement opening and closing of LUKS mappings
This commit is contained in:
Mike Fleetwood 2018-04-23 17:15:23 +01:00 committed by Curtis Gedak
parent 1bbb81f920
commit 957216f06c
4 changed files with 49 additions and 32 deletions

View File

@ -40,7 +40,7 @@ friend class PasswordRAMStoreTest; // To allow unit testing PasswordRAMStoreTes
// access to private methods. // access to private methods.
public: public:
static bool insert( const Glib::ustring & key, const char * password ); static bool store( const Glib::ustring & key, const char * password );
static bool erase( const Glib::ustring & key ); static bool erase( const Glib::ustring & key );
static const char * lookup( const Glib::ustring & key ); static const char * lookup( const Glib::ustring & key );

View File

@ -203,9 +203,17 @@ static PWStore single_pwstore;
// PasswordRAMStore public methods // PasswordRAMStore public methods
bool PasswordRAMStore::insert( const Glib::ustring & key, const char * password ) bool PasswordRAMStore::store( const Glib::ustring & key, const char * password )
{ {
return single_pwstore.insert( key, password ); const char * looked_up_pw = single_pwstore.lookup( key );
if ( looked_up_pw == NULL )
return single_pwstore.insert( key, password );
if ( strcmp( looked_up_pw, password ) == 0 )
return true;
return single_pwstore.erase( key )
&& single_pwstore.insert( key, password );
} }
bool PasswordRAMStore::erase( const Glib::ustring & key ) bool PasswordRAMStore::erase( const Glib::ustring & key )

View File

@ -2465,28 +2465,13 @@ bool Win_GParted::open_encrypted_partition( const Partition & partition,
bool success = ! Utils::execute_command( cmd, pw, output, error ); bool success = ! Utils::execute_command( cmd, pw, output, error );
hide_pulsebar(); hide_pulsebar();
if ( success && pw != NULL ) if ( success && pw != NULL )
{ // Save the password just entered and successfully used to open the LUKS
// Replace the password just successfully used to open the LUKS mapping if // mapping.
// it is different to the one already saved, or there is no saved PasswordRAMStore::store( partition.uuid, pw );
// password.
const char * stored_pw = PasswordRAMStore::lookup( partition.uuid );
if ( stored_pw != NULL &&
strcmp( pw, stored_pw ) == 0 )
{
PasswordRAMStore::erase( partition.uuid );
stored_pw = NULL;
}
if ( stored_pw == NULL )
{
PasswordRAMStore::insert( partition.uuid, pw );
}
}
else if ( ! success ) else if ( ! success )
{
// Erase the password used during for the failure to open the LUKS // Erase the password used during for the failure to open the LUKS
// mapping. // mapping.
PasswordRAMStore::erase( partition.uuid ); PasswordRAMStore::erase( partition.uuid );
}
message = ( success ) ? "" : _("Failed to open LUKS encryption"); message = ( success ) ? "" : _("Failed to open LUKS encryption");
return success; return success;

View File

@ -127,7 +127,7 @@ TEST_F( PasswordRAMStoreTest, SinglePassword )
{ {
// Test a single password can be stored, looked up and erased (and zeroed). // Test a single password can be stored, looked up and erased (and zeroed).
pw = "password"; pw = "password";
EXPECT_TRUE( PasswordRAMStore::insert( "key-single", pw.c_str() ) ); EXPECT_TRUE( PasswordRAMStore::store( "key-single", pw.c_str() ) );
looked_up_pw = PasswordRAMStore::lookup( "key-single" ); looked_up_pw = PasswordRAMStore::lookup( "key-single" );
EXPECT_STREQ( pw.c_str(), looked_up_pw ); EXPECT_STREQ( pw.c_str(), looked_up_pw );
@ -139,17 +139,41 @@ TEST_F( PasswordRAMStoreTest, SinglePassword )
EXPECT_TRUE( mem_is_zero( protected_mem, ProtectedMemSize ) ); EXPECT_TRUE( mem_is_zero( protected_mem, ProtectedMemSize ) );
} }
TEST_F( PasswordRAMStoreTest, DuplicatePassword ) TEST_F( PasswordRAMStoreTest, IdenticalPassword )
{ {
// Test storing a password with a duplicate key fails (and single password can be // Test a password can be saved twice with the same key and looked up (and the
// erased and zeroed). // single password can be erased and zeroed).
pw = "password"; pw = "password";
EXPECT_TRUE( PasswordRAMStore::insert( "key-single", pw.c_str() ) ); EXPECT_TRUE( PasswordRAMStore::store( "key-single", pw.c_str() ) );
EXPECT_TRUE( PasswordRAMStore::store( "key-single", pw.c_str() ) );
looked_up_pw = PasswordRAMStore::lookup( "key-single" ); looked_up_pw = PasswordRAMStore::lookup( "key-single" );
EXPECT_STREQ( pw.c_str(), looked_up_pw ); EXPECT_STREQ( pw.c_str(), looked_up_pw );
EXPECT_FALSE( PasswordRAMStore::insert( "key-single", pw.c_str() ) ); looked_up_len = strlen( looked_up_pw );
EXPECT_TRUE( PasswordRAMStore::erase( "key-single" ) );
EXPECT_TRUE( mem_is_zero( looked_up_pw, looked_up_len ) );
EXPECT_TRUE( mem_is_zero( protected_mem, ProtectedMemSize ) );
}
TEST_F( PasswordRAMStoreTest, ReplacePassword )
{
// Test a password can be saved and looked up, then saved again with a different
// password using the same key and looked up (and the single replaced password
// is erased and zeroed).
pw = "password";
EXPECT_TRUE( PasswordRAMStore::store( "key-single", pw.c_str() ) );
looked_up_pw = PasswordRAMStore::lookup( "key-single" );
EXPECT_STREQ( pw.c_str(), looked_up_pw );
pw = "password2";
EXPECT_TRUE( PasswordRAMStore::store( "key-single", pw.c_str() ) );
looked_up_pw = PasswordRAMStore::lookup( "key-single" );
EXPECT_STREQ( pw.c_str(), looked_up_pw );
looked_up_len = strlen( looked_up_pw ); looked_up_len = strlen( looked_up_pw );
EXPECT_TRUE( PasswordRAMStore::erase( "key-single" ) ); EXPECT_TRUE( PasswordRAMStore::erase( "key-single" ) );
@ -166,7 +190,7 @@ TEST_F( PasswordRAMStoreTest, OneHundredPasswordsForwards )
for ( i = 0 ; i < 100 ; i ++ ) for ( i = 0 ; i < 100 ; i ++ )
{ {
pw = gen_passwd( i ); pw = gen_passwd( i );
EXPECT_TRUE( PasswordRAMStore::insert( gen_key(i), pw.c_str() ) ); EXPECT_TRUE( PasswordRAMStore::store( gen_key(i), pw.c_str() ) );
} }
for ( i = 0 ; i < 100 ; i ++ ) for ( i = 0 ; i < 100 ; i ++ )
@ -196,7 +220,7 @@ TEST_F( PasswordRAMStoreTest, OneHundredPasswordsBackwards )
for ( i = 0 ; i < 100 ; i ++ ) for ( i = 0 ; i < 100 ; i ++ )
{ {
pw = gen_passwd( i ); pw = gen_passwd( i );
EXPECT_TRUE( PasswordRAMStore::insert( gen_key(i), pw.c_str() ) ); EXPECT_TRUE( PasswordRAMStore::store( gen_key(i), pw.c_str() ) );
} }
for ( i = 0 ; i < 100 ; i ++ ) for ( i = 0 ; i < 100 ; i ++ )
@ -224,7 +248,7 @@ TEST_F( PasswordRAMStoreTest, LongPassword )
// [Implementation knowledge: size] // [Implementation knowledge: size]
pw = std::string( ProtectedMemSize-1, 'X' ); pw = std::string( ProtectedMemSize-1, 'X' );
EXPECT_TRUE( PasswordRAMStore::insert( "key-long", pw.c_str() ) ); EXPECT_TRUE( PasswordRAMStore::store( "key-long", pw.c_str() ) );
looked_up_pw = PasswordRAMStore::lookup( "key-long" ); looked_up_pw = PasswordRAMStore::lookup( "key-long" );
EXPECT_STREQ( pw.c_str(), looked_up_pw ); EXPECT_STREQ( pw.c_str(), looked_up_pw );
@ -242,7 +266,7 @@ TEST_F( PasswordRAMStoreTest, TooLongPassword )
// [Implementation knowledge: size] // [Implementation knowledge: size]
std::string pw = std::string( ProtectedMemSize, 'X' ); std::string pw = std::string( ProtectedMemSize, 'X' );
EXPECT_FALSE( PasswordRAMStore::insert( "key-too-long", pw.c_str() ) ); EXPECT_FALSE( PasswordRAMStore::store( "key-too-long", pw.c_str() ) );
EXPECT_TRUE( mem_is_zero( protected_mem, ProtectedMemSize ) ); EXPECT_TRUE( mem_is_zero( protected_mem, ProtectedMemSize ) );
looked_up_pw = PasswordRAMStore::lookup( "key-too-long" ); looked_up_pw = PasswordRAMStore::lookup( "key-too-long" );
@ -260,7 +284,7 @@ TEST_F( PasswordRAMStoreTest, TotalErasure )
for ( i = 0 ; i < 100 ; i ++ ) for ( i = 0 ; i < 100 ; i ++ )
{ {
pw = gen_passwd( i ); pw = gen_passwd( i );
EXPECT_TRUE( PasswordRAMStore::insert( gen_key(i), pw.c_str() ) ); EXPECT_TRUE( PasswordRAMStore::store( gen_key(i), pw.c_str() ) );
} }
EXPECT_FALSE( mem_is_zero( protected_mem, ProtectedMemSize ) ); EXPECT_FALSE( mem_is_zero( protected_mem, ProtectedMemSize ) );