using System; using System.IO; using System.Linq; using Android.App; using Com.Keepassdroid.Database.Load; using Java.IO; using KeePassLib; using KeePassLib.Keys; using KeePassLib.Serialization; using Microsoft.VisualStudio.TestTools.UnitTesting; using keepass2android; using keepass2android.Io; using FileNotFoundException = System.IO.FileNotFoundException; namespace Kp2aUnitTests { [TestClass] internal partial class TestLoadDb : TestBase { private void RunLoadTest(string filenameWithoutDir, string password, string keyfile) { var app = PerformLoad(filenameWithoutDir, password, keyfile); Assert.AreEqual(6,app.GetDb().KpDatabase.RootGroup.Groups.Count()); Assert.AreEqual(2,app.GetDb().KpDatabase.RootGroup.Entries.Count()); } private IKp2aApp PerformLoad(string filenameWithoutDir, string password, string keyfile) { Android.Util.Log.Debug("KP2ATest", "Starting for " + filenameWithoutDir + " with " + password + "/" + keyfile); IKp2aApp app = new TestKp2aApp(); app.CreateNewDatabase(); bool loadSuccesful = false; var key = CreateKey(password, keyfile); string loadErrorMessage = ""; LoadDb task = new LoadDb(app, new IOConnectionInfo {Path = TestDbDirectory + filenameWithoutDir}, null, key, keyfile, new ActionOnFinish((success, message) => { loadErrorMessage = message; if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-( " + loadErrorMessage); return app; } [TestMethod] public void TestLoadWithPasswordOnly() { RunLoadTest("passwordonly.kdbx", DefaultPassword, ""); } [TestMethod] public void TestLoadKdb1() { var app = PerformLoad("keepass.kdb", "test", ""); //contents of the kdb file are a little different because the root group cannot have entries Assert.AreEqual(6, app.GetDb().KpDatabase.RootGroup.Groups.Count()); PwGroup generalGroup = app.GetDb().KpDatabase.RootGroup.Groups.Single(g => g.Name == "General"); Assert.AreEqual(2, generalGroup.Entries.Count()); foreach (PwEntry e in generalGroup.Entries) Assert.IsFalse(e.Binaries.Any()); } [TestMethod] public void TestLoadKdb1WithKeyfileByDirectCall() { ImporterV3 importer = new ImporterV3(); try { FileStream dbStream = new FileStream(TestDbDirectory+"withkeyfile_nopwd.kdb", FileMode.Open); FileStream keyfileStream = new FileStream(TestDbDirectory + "withkeyfile.key", FileMode.Open); /* for (int i = 0; i < 10; i++) { int b = keyfileStream.ReadByte(); Kp2aLog.Log(i+": " + b); } keyfileStream.Close(); Kp2aLog.Log("stream 2"); var keyfileStream2 = new MemoryStream(new KcpKeyFile(TestDbDirectory + "withkeyfile.key").RawFileData.ReadData()); for (int i = 0; i < 10; i++) { int b = keyfileStream2.ReadByte(); Kp2aLog.Log(i + ": " + b); }*/ importer.OpenDatabase(dbStream, "", keyfileStream); } catch (Exception e) { Kp2aLog.Log(e.ToString()); Assert.Fail("exception occured: " + e); } } [TestMethod] public void TestLoadKdb1WithKeyfile() { var app = PerformLoad("withkeyfile.kdb", "test", TestDbDirectory + "withkeyfile.key"); } [TestMethod] public void TestLoadKdb1WithKeyfileOnly() { var app = PerformLoad("withkeyfile_nopwd.kdb", "", TestDbDirectory + "withkeyfile.key"); } [TestMethod] public void TestLoadWithKeyfileOnly() { RunLoadTest("keyfileonly.kdbx", "", TestDbDirectory + "keyfile.txt"); } [TestMethod] public void TestLoadWithPasswordAndKeyfile() { RunLoadTest("PasswordAndKeyfile.kdbx", DefaultPassword, TestDbDirectory + "keyfile.txt"); } [TestMethod] public void TestLoadWithEmptyPassword() { RunLoadTest("EmptyPasswordAndKeyfile.kdbx", "", TestDbDirectory + "keyfile.txt"); } [TestMethod] public void TestLoadWithEmptyPasswordOnly() { RunLoadTest("EmptyPassword.kdbx", "", ""); } [TestMethod] public void LoadFromRemoteWithDomain() { //warning, looks like credentials are no longer valid var ioc = RemoteDomainIoc; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! var app = new TestKp2aApp(); app.ServerCertificateErrorResponse = true; //accept invalid cert app.CreateNewDatabase(); bool loadSuccesful = false; LoadDb task = new LoadDb(app, ioc, null, CreateKey("a"), null, new ActionOnFinish((success, message) => { if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-("); } [TestMethod] public void LoadErrorWithCertificateTrustFailure() { var ioc = RemoteCertFailureIoc; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! var app = new TestKp2aApp(); app.ServerCertificateErrorResponse = false; app.CreateNewDatabase(); bool loadSuccesful = false; string theMessage = ""; LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) => { if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; theMessage = message; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsFalse(loadSuccesful, "database should not be loaded because invalid certificates are not accepted"); Assert.AreEqual(theMessage, UiStringKey.ErrorOcurred +" "+UiStringKey.CertificateFailure); } [TestMethod] public void LoadWithAcceptedCertificateTrustFailure() { var ioc = RemoteCertFailureIoc; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! var app = new TestKp2aApp(); app.ServerCertificateErrorResponse = true; app.CreateNewDatabase(); bool loadSuccesful = false; LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) => { if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsTrue(loadSuccesful, "database should be loaded because invalid certificates are accepted"); } [TestMethod] public void LoadFromRemote1And1() { var ioc = RemoteIoc1and1; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! IKp2aApp app = new TestKp2aApp(); app.CreateNewDatabase(); bool loadSuccesful = false; LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) => { if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-("); } [TestMethod] public void LoadAndSaveFromRemote1And1Ftp() { var ioc = RemoteIoc1and1Ftp; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! var app = new TestKp2aApp(); app.CreateNewDatabase(); bool loadSuccesful = false; LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) => { if (!success) Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsTrue(loadSuccesful, "didn't succesfully load database :-("); Assert.IsTrue(TrySaveDatabase(app), "didn't successfully save database."); } [TestMethod] public void LoadFromRemote1And1NonExisting() { var ioc = RemoteIoc1and1NonExisting; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! IKp2aApp app = new TestKp2aApp(); app.CreateNewDatabase(); bool loadSuccesful = false; bool gotError = false; LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) => { if (!success) { Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); gotError = true; } loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsFalse(loadSuccesful); Assert.IsTrue(gotError); } [TestMethod] public void LoadFromRemote1And1WrongCredentials() { var ioc = RemoteIoc1and1WrongCredentials; //note: this property is defined in "TestLoadDbCredentials.cs" which is deliberately excluded from Git because the credentials are not public! IKp2aApp app = new TestKp2aApp(); app.CreateNewDatabase(); bool loadSuccesful = false; bool gotError = false; LoadDb task = new LoadDb(app, ioc, null, CreateKey("test"), null, new ActionOnFinish((success, message) => { if (!success) { Android.Util.Log.Debug("KP2ATest", "error loading db: " + message); gotError = true; } loadSuccesful = success; }) ); ProgressTask pt = new ProgressTask(app, Application.Context, task); Android.Util.Log.Debug("KP2ATest", "Running ProgressTask"); pt.Run(); pt.JoinWorkerThread(); Android.Util.Log.Debug("KP2ATest", "PT.run finished"); Assert.IsFalse(loadSuccesful); Assert.IsTrue(gotError); } [TestMethod] public void FileNotFoundExceptionWithWebDav() { var app = new TestKp2aApp(); var fileStorage = app.FileStorage; //should work: using (var stream = fileStorage.OpenFileForRead(RemoteIoc1and1)) { stream.CopyTo(new MemoryStream()); } //shouldn't give FileNotFound: bool gotException = false; try { using (var stream = fileStorage.OpenFileForRead(RemoteIoc1and1WrongCredentials)) { stream.CopyTo(new MemoryStream()); } } catch (FileNotFoundException) { Assert.Fail("shouldn't get FileNotFound with wrong credentials"); } catch (Exception e) { Kp2aLog.Log("received "+e); gotException = true; } Assert.IsTrue(gotException); //should give FileNotFound: gotException = false; try { using (var stream = fileStorage.OpenFileForRead(RemoteIoc1and1NonExisting)) { stream.CopyTo(new MemoryStream()); } } catch (FileNotFoundException) { gotException = true; } Assert.IsTrue(gotException); } [TestMethod] public void TestLoadKdbpWithPasswordOnly() { RunLoadTest("passwordonly.kdbp", DefaultPassword, ""); } } }