fix crashes when keyfile filename is not yet encoded and when loading key file (no network in main thread!)

increase version
This commit is contained in:
Philipp Crocoll 2014-12-07 05:14:50 +01:00
parent 4ab8894503
commit ff525bd655
4 changed files with 172 additions and 109 deletions

View File

@ -88,6 +88,8 @@ namespace keepass2android
private const int RequestCodePrepareOtpAuxFile = 1001; private const int RequestCodePrepareOtpAuxFile = 1001;
private const int RequestCodeChallengeYubikey = 1002; private const int RequestCodeChallengeYubikey = 1002;
private const int RequestCodeSelectKeyfile = 1003; private const int RequestCodeSelectKeyfile = 1003;
private const int RequestCodePrepareKeyFile = 1004;
private Task<MemoryStream> _loadDbTask; private Task<MemoryStream> _loadDbTask;
private IOConnectionInfo _ioConnection; private IOConnectionInfo _ioConnection;
@ -278,7 +280,22 @@ namespace keepass2android
break; break;
case (Result)FileStorageResults.FileUsagePrepared: case (Result)FileStorageResults.FileUsagePrepared:
if (requestCode == RequestCodePrepareDbFile) if (requestCode == RequestCodePrepareDbFile)
{
if (KeyProviderType == KeyProviders.KeyFile)
{
var iocKeyfile = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
App.Kp2a.GetFileStorage(iocKeyfile)
.PrepareFileUsage(new FileStorageSetupInitiatorActivity(this, OnActivityResult, null), iocKeyfile,
RequestCodePrepareKeyFile, false);
}
else
PerformLoadDatabase();
}
if (requestCode == RequestCodePrepareKeyFile)
{
PerformLoadDatabase(); PerformLoadDatabase();
}
if (requestCode == RequestCodePrepareOtpAuxFile) if (requestCode == RequestCodePrepareOtpAuxFile)
{ {
if (_keyFileOrProvider == KeyProviderIdChallenge) if (_keyFileOrProvider == KeyProviderIdChallenge)
@ -551,7 +568,17 @@ namespace keepass2android
else else
{ {
SetIoConnectionFromIntent(_ioConnection, i); SetIoConnectionFromIntent(_ioConnection, i);
_keyFileOrProvider = i.GetStringExtra(KeyKeyfile); var keyFileFromIntent = i.GetStringExtra(KeyKeyfile);
if (keyFileFromIntent != null)
{
Kp2aLog.Log("try get keyfile from intent");
_keyFileOrProvider = IOConnectionInfo.SerializeToString(IOConnectionInfo.FromPath(keyFileFromIntent));
Kp2aLog.Log("try get keyfile from intent ok");
}
else
{
_keyFileOrProvider = null;
}
_password = i.GetStringExtra(KeyPassword) ?? ""; _password = i.GetStringExtra(KeyPassword) ?? "";
if (string.IsNullOrEmpty(_keyFileOrProvider)) if (string.IsNullOrEmpty(_keyFileOrProvider))
{ {
@ -897,9 +924,45 @@ namespace keepass2android
private void PerformLoadDatabase() private void PerformLoadDatabase()
{ {
//put loading into background thread to allow loading the key file (potentially over network)
new SimpleLoadingDialog(this, GetString(Resource.String.loading),
true, () =>
{
CompositeKey compositeKey;
if (!CreateCompositeKey(out compositeKey)) return (() => { });
return () => { PerformLoadDatabaseWithCompositeKey(compositeKey); };
}).Execute();
//no need to check for validity of password because if this method is called, the Ok button was enabled (i.e. there was a valid password)
CompositeKey compositeKey = new CompositeKey(); }
private void PerformLoadDatabaseWithCompositeKey(CompositeKey compositeKey)
{
CheckBox cbQuickUnlock = (CheckBox) FindViewById(Resource.Id.enable_quickunlock);
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
//avoid password being visible while loading:
_showPassword = false;
MakePasswordMaskedOrVisible();
Handler handler = new Handler();
OnFinish onFinish = new AfterLoad(handler, this);
_performingLoad = true;
LoadDb task = (KeyProviderType == KeyProviders.Otp)
? new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider,
onFinish, this)
: new LoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider, onFinish);
_loadDbTask = null; // prevent accidental re-use
SetNewDefaultFile();
new ProgressTask(App.Kp2a, this, task).Run();
}
private bool CreateCompositeKey(out CompositeKey compositeKey)
{
//no need to check for validity of password because if this method is called, the Ok button was enabled (i.e. there was a valid password)
compositeKey = new CompositeKey();
compositeKey.AddUserKey(new KcpPassword(_password)); compositeKey.AddUserKey(new KcpPassword(_password));
if (KeyProviderType == KeyProviders.KeyFile) if (KeyProviderType == KeyProviders.KeyFile)
{ {
@ -913,24 +976,22 @@ namespace keepass2android
byte[] keyfileData = StreamToMemoryStream(stream).ToArray(); byte[] keyfileData = StreamToMemoryStream(stream).ToArray();
compositeKey.AddUserKey(new KcpKeyFile(keyfileData, ioc, true)); compositeKey.AddUserKey(new KcpKeyFile(keyfileData, ioc, true));
} }
} }
catch (System.IO.FileNotFoundException e) catch (System.IO.FileNotFoundException e)
{ {
Kp2aLog.Log(e.ToString()); Kp2aLog.Log(e.ToString());
Toast.MakeText(this, App.Kp2a.GetResourceString(UiStringKey.keyfile_does_not_exist), ToastLength.Long).Show(); Toast.MakeText(this, App.Kp2a.GetResourceString(UiStringKey.keyfile_does_not_exist), ToastLength.Long).Show();
return; return false;
} }
catch (Exception e) catch (Exception e)
{ {
Kp2aLog.Log(e.ToString()); Kp2aLog.Log(e.ToString());
Toast.MakeText(this, e.Message, ToastLength.Long).Show(); Toast.MakeText(this, e.Message, ToastLength.Long).Show();
return; return false;
} }
} }
else if (KeyProviderType == KeyProviders.Otp) else if (KeyProviderType == KeyProviders.Otp)
{ {
try try
{ {
var lOtps = GetOtpsFromUi(); var lOtps = GetOtpsFromUi();
@ -942,7 +1003,7 @@ namespace keepass2android
Kp2aLog.Log(e.ToString()); Kp2aLog.Log(e.ToString());
Toast.MakeText(this, GetString(Resource.String.OtpKeyError), ToastLength.Long).Show(); Toast.MakeText(this, GetString(Resource.String.OtpKeyError), ToastLength.Long).Show();
return; return false;
} }
compositeKey.AddUserKey(new KcpCustomKey(OathHotpKeyProv.Name, _otpInfo.Secret, true)); compositeKey.AddUserKey(new KcpCustomKey(OathHotpKeyProv.Name, _otpInfo.Secret, true));
} }
@ -951,7 +1012,7 @@ namespace keepass2android
Spinner stpDataFmtSpinner = FindViewById<Spinner>(Resource.Id.otpsecret_format_spinner); Spinner stpDataFmtSpinner = FindViewById<Spinner>(Resource.Id.otpsecret_format_spinner);
EditText secretEdit = FindViewById<EditText>(Resource.Id.pass_otpsecret); EditText secretEdit = FindViewById<EditText>(Resource.Id.pass_otpsecret);
byte[] pbSecret = EncodingUtil.ParseKey(secretEdit.Text, (OtpDataFmt)stpDataFmtSpinner.SelectedItemPosition); byte[] pbSecret = EncodingUtil.ParseKey(secretEdit.Text, (OtpDataFmt) stpDataFmtSpinner.SelectedItemPosition);
if (pbSecret != null) if (pbSecret != null)
{ {
compositeKey.AddUserKey(new KcpCustomKey(OathHotpKeyProv.Name, pbSecret, true)); compositeKey.AddUserKey(new KcpCustomKey(OathHotpKeyProv.Name, pbSecret, true));
@ -959,34 +1020,14 @@ namespace keepass2android
else else
{ {
Toast.MakeText(this, Resource.String.CouldntParseOtpSecret, ToastLength.Long).Show(); Toast.MakeText(this, Resource.String.CouldntParseOtpSecret, ToastLength.Long).Show();
return; return false;
} }
} }
else if (KeyProviderType == KeyProviders.Challenge) else if (KeyProviderType == KeyProviders.Challenge)
{ {
compositeKey.AddUserKey(new KcpCustomKey(KeeChallengeProv.Name, _challengeSecret, true)); compositeKey.AddUserKey(new KcpCustomKey(KeeChallengeProv.Name, _challengeSecret, true));
}
} return true;
CheckBox cbQuickUnlock = (CheckBox) FindViewById(Resource.Id.enable_quickunlock);
App.Kp2a.SetQuickUnlockEnabled(cbQuickUnlock.Checked);
//avoid password being visible while loading:
_showPassword = false;
MakePasswordMaskedOrVisible();
Handler handler = new Handler();
OnFinish onFinish = new AfterLoad(handler, this);
_performingLoad = true;
LoadDb task = (KeyProviderType == KeyProviders.Otp) ?
new SaveOtpAuxFileAndLoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider, onFinish, this)
:
new LoadDb(App.Kp2a, _ioConnection, _loadDbTask, compositeKey, _keyFileOrProvider, onFinish);
_loadDbTask = null; // prevent accidental re-use
SetNewDefaultFile();
new ProgressTask(App.Kp2a, this, task).Run();
} }
private List<string> GetOtpsFromUi() private List<string> GetOtpsFromUi()
@ -1251,8 +1292,26 @@ namespace keepass2android
private String GetKeyFile(String filename) { private String GetKeyFile(String filename) {
if ( _rememberKeyfile ) { if ( _rememberKeyfile ) {
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(filename); string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(filename);
if (keyfile == "") if (String.IsNullOrEmpty(keyfile))
return null; //signal no key file return null; //signal no key file
//test if the filename is properly encoded.
try
{
Kp2aLog.Log("test if stored filename is ok");
IOConnectionInfo.UnserializeFromString(keyfile);
Kp2aLog.Log("...ok");
}
catch (Exception e)
{
//it's not. This is probably because we're upgrading from app version <= 45
//where the keyfile was stored plain text and not serialized
Kp2aLog.Log("no, it's not: "+e.GetType().Name);
var serializedKeyFile = IOConnectionInfo.SerializeToString(IOConnectionInfo.FromPath(keyfile));
Kp2aLog.Log("now it is!");
return serializedKeyFile;
}
return keyfile; return keyfile;
} else { } else {
return null; return null;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="46" android:versionName="0.9.5-preview" package="keepass2android.keepass2android" android:installLocation="auto"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="47" android:versionName="0.9.5-preview2" package="keepass2android.keepass2android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" /> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" />
<permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" /> <permission android:description="@string/permission_desc" android:icon="@drawable/ic_launcher" android:label="KP2A internal file browsing" android:name="keepass2android.keepass2android.permission.KP2aInternalFileBrowsing" android:protectionLevel="signature" />
<application android:label="keepass2android" android:icon="@drawable/ic_launcher"> <application android:label="keepass2android" android:icon="@drawable/ic_launcher">

View File

@ -4667,53 +4667,56 @@ namespace keepass2android
// aapt resource value: 0x7f0702eb // aapt resource value: 0x7f0702eb
public const int CertificateWarning = 2131165931; public const int CertificateWarning = 2131165931;
// aapt resource value: 0x7f070309
public const int ChangeLog = 2131165961;
// aapt resource value: 0x7f070308 // aapt resource value: 0x7f070308
public const int ChangeLog = 2131165960; public const int ChangeLog_0_7 = 2131165960;
// aapt resource value: 0x7f070307
public const int ChangeLog_0_7 = 2131165959;
// aapt resource value: 0x7f070305
public const int ChangeLog_0_8 = 2131165957;
// aapt resource value: 0x7f070304
public const int ChangeLog_0_8_1 = 2131165956;
// aapt resource value: 0x7f070303
public const int ChangeLog_0_8_2 = 2131165955;
// aapt resource value: 0x7f070302
public const int ChangeLog_0_8_3 = 2131165954;
// aapt resource value: 0x7f070301
public const int ChangeLog_0_8_4 = 2131165953;
// aapt resource value: 0x7f070300
public const int ChangeLog_0_8_5 = 2131165952;
// aapt resource value: 0x7f0702ff
public const int ChangeLog_0_8_6 = 2131165951;
// aapt resource value: 0x7f0702fe
public const int ChangeLog_0_9 = 2131165950;
// aapt resource value: 0x7f0702fd
public const int ChangeLog_0_9_1 = 2131165949;
// aapt resource value: 0x7f0702fc
public const int ChangeLog_0_9_2 = 2131165948;
// aapt resource value: 0x7f0702fb
public const int ChangeLog_0_9_3 = 2131165947;
// aapt resource value: 0x7f0702fa
public const int ChangeLog_0_9_3_r5 = 2131165946;
// aapt resource value: 0x7f0702f9
public const int ChangeLog_0_9_4 = 2131165945;
// aapt resource value: 0x7f070306 // aapt resource value: 0x7f070306
public const int ChangeLog_keptDonate = 2131165958; public const int ChangeLog_0_8 = 2131165958;
// aapt resource value: 0x7f070305
public const int ChangeLog_0_8_1 = 2131165957;
// aapt resource value: 0x7f070304
public const int ChangeLog_0_8_2 = 2131165956;
// aapt resource value: 0x7f070303
public const int ChangeLog_0_8_3 = 2131165955;
// aapt resource value: 0x7f070302
public const int ChangeLog_0_8_4 = 2131165954;
// aapt resource value: 0x7f070301
public const int ChangeLog_0_8_5 = 2131165953;
// aapt resource value: 0x7f070300
public const int ChangeLog_0_8_6 = 2131165952;
// aapt resource value: 0x7f0702ff
public const int ChangeLog_0_9 = 2131165951;
// aapt resource value: 0x7f0702fe
public const int ChangeLog_0_9_1 = 2131165950;
// aapt resource value: 0x7f0702fd
public const int ChangeLog_0_9_2 = 2131165949;
// aapt resource value: 0x7f0702fc
public const int ChangeLog_0_9_3 = 2131165948;
// aapt resource value: 0x7f0702fb
public const int ChangeLog_0_9_3_r5 = 2131165947;
// aapt resource value: 0x7f0702fa
public const int ChangeLog_0_9_4 = 2131165946;
// aapt resource value: 0x7f0702f9
public const int ChangeLog_0_9_5 = 2131165945;
// aapt resource value: 0x7f070307
public const int ChangeLog_keptDonate = 2131165959;
// aapt resource value: 0x7f0702f7 // aapt resource value: 0x7f0702f7
public const int ChangeLog_title = 2131165943; public const int ChangeLog_title = 2131165943;
@ -5600,11 +5603,11 @@ namespace keepass2android
// aapt resource value: 0x7f070173 // aapt resource value: 0x7f070173
public const int brackets = 2131165555; public const int brackets = 2131165555;
// aapt resource value: 0x7f07030b
public const int browser_intall_text = 2131165963;
// aapt resource value: 0x7f07030c // aapt resource value: 0x7f07030c
public const int building_search_idx = 2131165964; public const int browser_intall_text = 2131165964;
// aapt resource value: 0x7f07030d
public const int building_search_idx = 2131165965;
// aapt resource value: 0x7f0702b5 // aapt resource value: 0x7f0702b5
public const int button_change_location = 2131165877; public const int button_change_location = 2131165877;
@ -5765,14 +5768,14 @@ namespace keepass2android
// aapt resource value: 0x7f070119 // aapt resource value: 0x7f070119
public const int db_key = 2131165465; public const int db_key = 2131165465;
// aapt resource value: 0x7f07030d
public const int decrypting_db = 2131165965;
// aapt resource value: 0x7f07030e // aapt resource value: 0x7f07030e
public const int decrypting_entry = 2131165966; public const int decrypting_db = 2131165966;
// aapt resource value: 0x7f07030f // aapt resource value: 0x7f07030f
public const int default_checkbox = 2131165967; public const int decrypting_entry = 2131165967;
// aapt resource value: 0x7f070310
public const int default_checkbox = 2131165968;
// aapt resource value: 0x7f07010b // aapt resource value: 0x7f07010b
public const int default_file_path = 2131165451; public const int default_file_path = 2131165451;
@ -5795,8 +5798,8 @@ namespace keepass2android
// aapt resource value: 0x7f070120 // aapt resource value: 0x7f070120
public const int design_key = 2131165472; public const int design_key = 2131165472;
// aapt resource value: 0x7f070309 // aapt resource value: 0x7f07030a
public const int design_title = 2131165961; public const int design_title = 2131165962;
// aapt resource value: 0x7f070180 // aapt resource value: 0x7f070180
public const int digits = 2131165568; public const int digits = 2131165568;
@ -5858,8 +5861,8 @@ namespace keepass2android
// aapt resource value: 0x7f070184 // aapt resource value: 0x7f070184
public const int entry_accessed = 2131165572; public const int entry_accessed = 2131165572;
// aapt resource value: 0x7f070310 // aapt resource value: 0x7f070311
public const int entry_and_or = 2131165968; public const int entry_and_or = 2131165969;
// aapt resource value: 0x7f070196 // aapt resource value: 0x7f070196
public const int entry_binaries = 2131165590; public const int entry_binaries = 2131165590;
@ -5915,8 +5918,8 @@ namespace keepass2android
// aapt resource value: 0x7f0702bd // aapt resource value: 0x7f0702bd
public const int error_adding_keyfile = 2131165885; public const int error_adding_keyfile = 2131165885;
// aapt resource value: 0x7f070311 // aapt resource value: 0x7f070312
public const int error_arc4 = 2131165969; public const int error_arc4 = 2131165970;
// aapt resource value: 0x7f070197 // aapt resource value: 0x7f070197
public const int error_can_not_handle_uri = 2131165591; public const int error_can_not_handle_uri = 2131165591;
@ -5930,8 +5933,8 @@ namespace keepass2android
// aapt resource value: 0x7f07019a // aapt resource value: 0x7f07019a
public const int error_database_exists = 2131165594; public const int error_database_exists = 2131165594;
// aapt resource value: 0x7f07030a // aapt resource value: 0x7f07030b
public const int error_database_settings = 2131165962; public const int error_database_settings = 2131165963;
// aapt resource value: 0x7f07019b // aapt resource value: 0x7f07019b
public const int error_database_settinoverrgs = 2131165595; public const int error_database_settinoverrgs = 2131165595;
@ -5960,8 +5963,8 @@ namespace keepass2android
// aapt resource value: 0x7f0701a2 // aapt resource value: 0x7f0701a2
public const int error_nopass = 2131165602; public const int error_nopass = 2131165602;
// aapt resource value: 0x7f070312 // aapt resource value: 0x7f070313
public const int error_out_of_memory = 2131165970; public const int error_out_of_memory = 2131165971;
// aapt resource value: 0x7f0701a3 // aapt resource value: 0x7f0701a3
public const int error_pass_gen_type = 2131165603; public const int error_pass_gen_type = 2131165603;
@ -5972,8 +5975,8 @@ namespace keepass2android
// aapt resource value: 0x7f0701a5 // aapt resource value: 0x7f0701a5
public const int error_rounds_not_number = 2131165605; public const int error_rounds_not_number = 2131165605;
// aapt resource value: 0x7f070313 // aapt resource value: 0x7f070314
public const int error_rounds_too_large = 2131165971; public const int error_rounds_too_large = 2131165972;
// aapt resource value: 0x7f07023f // aapt resource value: 0x7f07023f
public const int error_string_key = 2131165759; public const int error_string_key = 2131165759;
@ -6161,11 +6164,11 @@ namespace keepass2android
// aapt resource value: 0x7f070204 // aapt resource value: 0x7f070204
public const int insert_element_here = 2131165700; public const int insert_element_here = 2131165700;
// aapt resource value: 0x7f070314
public const int install_from_market = 2131165972;
// aapt resource value: 0x7f070315 // aapt resource value: 0x7f070315
public const int install_from_website = 2131165973; public const int install_from_market = 2131165973;
// aapt resource value: 0x7f070316
public const int install_from_website = 2131165974;
// aapt resource value: 0x7f0701ba // aapt resource value: 0x7f0701ba
public const int invalid_algorithm = 2131165626; public const int invalid_algorithm = 2131165626;
@ -6380,8 +6383,8 @@ namespace keepass2android
// aapt resource value: 0x7f0701d4 // aapt resource value: 0x7f0701d4
public const int menu_hide_password = 2131165652; public const int menu_hide_password = 2131165652;
// aapt resource value: 0x7f070316 // aapt resource value: 0x7f070317
public const int menu_homepage = 2131165974; public const int menu_homepage = 2131165975;
// aapt resource value: 0x7f0701d5 // aapt resource value: 0x7f0701d5
public const int menu_lock = 2131165653; public const int menu_lock = 2131165653;

View File

@ -230,7 +230,7 @@
<string name="QuickUnlockDefaultEnabled_title">Enable QuickUnlock by default</string> <string name="QuickUnlockDefaultEnabled_title">Enable QuickUnlock by default</string>
<string name="QuickUnlockDefaultEnabled_summary">Defines whether QuickUnlock is enabled by default or not.</string> <string name="QuickUnlockDefaultEnabled_summary">Defines whether QuickUnlock is enabled by default or not.</string>
<string name="ViewDatabaseSecure_title">Protect database display</string> <string name="ViewDatabaseSecure_title">Protect database display</string>
<string name="ViewDatabaseSecure_summary">Protect database display</string> <string name="ViewDatabaseSecure_summary">If enabled, no screenshots are allowed and no thumbnail of the app is displayed in the Recent Apps list.</string>
<string name="QuickUnlockIconHidden_title">Hide QuickUnlock icon</string> <string name="QuickUnlockIconHidden_title">Hide QuickUnlock icon</string>
<string name="QuickUnlockIconHidden_summary">QuickUnlock unfortunately does not work without displaying a notification icon. Select this option to use a transparent icon.</string> <string name="QuickUnlockIconHidden_summary">QuickUnlock unfortunately does not work without displaying a notification icon. Select this option to use a transparent icon.</string>
<string name="QuickUnlockIconHidden16_title">Hide QuickUnlock icon</string> <string name="QuickUnlockIconHidden16_title">Hide QuickUnlock icon</string>
@ -498,6 +498,7 @@
* Fixed issue with loading .kdb files (Keepass 1) on Nexus 5 with Android Lollipop\n * Fixed issue with loading .kdb files (Keepass 1) on Nexus 5 with Android Lollipop\n
* Added option to prevent taking screenshots/displaying app in recent apps list\n * Added option to prevent taking screenshots/displaying app in recent apps list\n
* Fixed issue with Google Drive file storage\n * Fixed issue with Google Drive file storage\n
* Allow key files on deliberate storage types\n
* Updated build tools --> apk size increased :-(\n * Updated build tools --> apk size increased :-(\n
I have promised some more changes. They will come with the next release - sorry. I wanted to publish these hot fixes as soon as possible. I have promised some more changes. They will come with the next release - sorry. I wanted to publish these hot fixes as soon as possible.
</string> </string>