blob: e204c97e41e50d387d30be5b097e4c260003a620 [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "smbfs/smbfs_bootstrap_impl.h"
#include <memory>
#include <utility>
#include <vector>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/run_loop.h>
#include <base/test/bind_test_util.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/core/embedder/embedder.h>
#include <mojo/public/cpp/system/platform_handle.h>
#include <libpasswordprovider/password.h>
#include "smbfs/smb_filesystem.h"
#include "smbfs/smbfs_impl.h"
namespace smbfs {
namespace {
using ::testing::_;
using ::testing::Return;
using ::testing::Unused;
using ::testing::WithArg;
const char kSharePath[] = "smb://server/share";
const char kWorkgroup[] = "my-workgroup";
const char kUsername[] = "my-username";
const char kPassword[] = "my-super-secret-password";
const char kKerberosGuid[] = "1234-5678-my-guid";
const char kAccountHash[] = "00112233445566778899aa";
class MockSmbFilesystemDelegate : public SmbFilesystem::Delegate {
public:
MOCK_METHOD(void,
RequestCredentials,
(RequestCredentialsCallback),
(override));
};
class MockSmbFilesystem : public SmbFilesystem {
public:
MockSmbFilesystem() : SmbFilesystem(&delegate_, kSharePath) {}
MOCK_METHOD(ConnectError, EnsureConnected, (), (override));
MOCK_METHOD(void,
SetResolvedAddress,
(const std::vector<uint8_t>&),
(override));
private:
MockSmbFilesystemDelegate delegate_;
};
class MockBootstrapDelegate : public SmbFsBootstrapImpl::Delegate {
public:
MOCK_METHOD(void,
SetupKerberos,
(mojom::KerberosConfigPtr,
base::OnceCallback<void(bool success)>),
(override));
MOCK_METHOD(void, OnPasswordFilePathSet, (const base::FilePath&), (override));
};
class MockSmbFsDelegate : public mojom::SmbFsDelegate {
public:
explicit MockSmbFsDelegate(mojom::SmbFsDelegateRequest request)
: binding_(this, std::move(request)) {}
MOCK_METHOD(void,
RequestCredentials,
(RequestCredentialsCallback),
(override));
private:
mojo::Binding<mojom::SmbFsDelegate> binding_;
};
std::unique_ptr<password_provider::Password> MakePassword(
const std::string& password) {
int fds[2];
CHECK(base::CreateLocalNonBlockingPipe(fds));
base::ScopedFD read_fd(fds[0]);
base::ScopedFD write_fd(fds[1]);
CHECK(base::WriteFileDescriptor(write_fd.get(), password.data(),
password.size()));
return password_provider::Password::CreateFromFileDescriptor(read_fd.get(),
password.size());
}
class TestSmbFsBootstrapImpl : public testing::Test {
public:
void SetUp() override {
ResetDelegate();
ASSERT_TRUE(daemon_store_dir_.CreateUniqueTempDir());
}
void ResetDelegate() {
smbfs_delegate_ptr_.reset();
mock_smbfs_delegate_ = std::make_unique<MockSmbFsDelegate>(
mojo::MakeRequest(&smbfs_delegate_ptr_));
}
protected:
base::test::TaskEnvironment task_environment{
base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
base::test::TaskEnvironment::MainThreadType::IO};
MockBootstrapDelegate mock_delegate_;
mojom::SmbFsDelegatePtr smbfs_delegate_ptr_;
std::unique_ptr<MockSmbFsDelegate> mock_smbfs_delegate_;
base::ScopedTempDir daemon_store_dir_;
};
TEST_F(TestSmbFsBootstrapImpl, GuestAuth) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.share_path, kSharePath);
EXPECT_FALSE(options.allow_ntlm);
EXPECT_TRUE(options.credentials->workgroup.empty());
EXPECT_TRUE(options.credentials->username.empty());
EXPECT_FALSE(options.credentials->password);
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kOk));
EXPECT_CALL(*fs, SetResolvedAddress(std::vector<uint8_t>({1, 2, 3, 4})))
.Times(1);
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
bool bootstrap_done = false;
boostrap_impl.Start(base::BindLambdaForTesting(
[&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) {
EXPECT_TRUE(fs);
bootstrap_done = true;
}));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->resolved_host =
mojom::IPAddress::New(std::vector<uint8_t>({1, 2, 3, 4}));
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kOk, mount_error);
EXPECT_TRUE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_TRUE(bootstrap_done);
}
TEST_F(TestSmbFsBootstrapImpl, UsernamePasswordAuth) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.share_path, kSharePath);
EXPECT_TRUE(options.allow_ntlm);
EXPECT_EQ(options.credentials->workgroup, kWorkgroup);
EXPECT_EQ(options.credentials->username, kUsername);
EXPECT_EQ(options.credentials->password->GetRaw(),
std::string(kPassword));
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kOk));
EXPECT_CALL(*fs, SetResolvedAddress(_)).Times(0);
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
bool bootstrap_done = false;
boostrap_impl.Start(base::BindLambdaForTesting(
[&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) {
EXPECT_TRUE(fs);
bootstrap_done = true;
}));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->workgroup = kWorkgroup;
mount_options->username = kUsername;
mount_options->password = MakePassword(kPassword);
mount_options->allow_ntlm = true;
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kOk, mount_error);
EXPECT_TRUE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_TRUE(bootstrap_done);
}
TEST_F(TestSmbFsBootstrapImpl, KerberosAuth) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.share_path, kSharePath);
EXPECT_FALSE(options.allow_ntlm);
EXPECT_EQ(options.credentials->workgroup, kWorkgroup);
EXPECT_EQ(options.credentials->username, kUsername);
EXPECT_FALSE(options.credentials->password);
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kOk));
EXPECT_CALL(*fs, SetResolvedAddress(_)).Times(0);
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
EXPECT_CALL(mock_delegate_, SetupKerberos(_, _))
.WillOnce([](mojom::KerberosConfigPtr config,
base::OnceCallback<void(bool success)> callback) {
EXPECT_EQ(config->source, mojom::KerberosConfig::Source::kKerberos);
EXPECT_EQ(config->identity, kKerberosGuid);
std::move(callback).Run(true);
});
bool bootstrap_done = false;
boostrap_impl.Start(base::BindLambdaForTesting(
[&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) {
EXPECT_TRUE(fs);
bootstrap_done = true;
}));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->workgroup = kWorkgroup;
mount_options->username = kUsername;
mount_options->kerberos_config = mojom::KerberosConfig::New(
mojom::KerberosConfig::Source::kKerberos, kKerberosGuid);
// These two options will be ignored when Kerberos is being used.
mount_options->password = MakePassword(kPassword);
mount_options->resolved_host =
mojom::IPAddress::New(std::vector<uint8_t>({1, 2, 3, 4}));
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kOk, mount_error);
EXPECT_TRUE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_TRUE(bootstrap_done);
}
TEST_F(TestSmbFsBootstrapImpl, SkipConnect) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.share_path, kSharePath);
EXPECT_FALSE(options.allow_ntlm);
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
// Expect that EnsureConnected() is never called when skip_connect mount
// option is set.
EXPECT_CALL(*fs, EnsureConnected()).Times(0);
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
bool bootstrap_done = false;
boostrap_impl.Start(base::BindLambdaForTesting(
[&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) {
EXPECT_TRUE(fs);
bootstrap_done = true;
}));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->skip_connect = true;
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kOk, mount_error);
EXPECT_TRUE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
EXPECT_TRUE(bootstrap_done);
}
TEST_F(TestSmbFsBootstrapImpl, Disconnect) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
// FAIL() can only be used in a function that returns void.
ADD_FAILURE();
return nullptr;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
base::RunLoop run_loop;
boostrap_impl.Start(base::BindLambdaForTesting(
[&run_loop](std::unique_ptr<SmbFilesystem> fs,
mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) {
EXPECT_FALSE(fs);
run_loop.Quit();
}));
boostrap_ptr.reset();
run_loop.Run();
}
TEST_F(TestSmbFsBootstrapImpl, InvalidPath) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
ADD_FAILURE();
return nullptr;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
boostrap_impl.Start(base::BindOnce(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { FAIL(); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = "bad-path";
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kInvalidUrl, mount_error);
EXPECT_FALSE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(TestSmbFsBootstrapImpl, KerberosSetupFailure) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
ADD_FAILURE();
return nullptr;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
EXPECT_CALL(mock_delegate_, SetupKerberos(_, _))
.WillOnce([](mojom::KerberosConfigPtr config,
base::OnceCallback<void(bool success)> callback) {
std::move(callback).Run(false);
});
boostrap_impl.Start(base::BindOnce(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { FAIL(); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->workgroup = kWorkgroup;
mount_options->username = kUsername;
mount_options->kerberos_config = mojom::KerberosConfig::New(
mojom::KerberosConfig::Source::kKerberos, kKerberosGuid);
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kUnknown, mount_error);
EXPECT_FALSE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(TestSmbFsBootstrapImpl, ConnectionAuthFailure) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.share_path, kSharePath);
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kAccessDenied));
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
boostrap_impl.Start(base::BindOnce(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { FAIL(); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kAccessDenied, mount_error);
EXPECT_FALSE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(TestSmbFsBootstrapImpl, UnsupportedProtocolSmb1) {
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.share_path, kSharePath);
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kSmb1Unsupported));
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr), fs_factory,
&mock_delegate_,
daemon_store_dir_.GetPath());
boostrap_impl.Start(base::BindOnce(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { FAIL(); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kInvalidProtocol, mount_error);
EXPECT_FALSE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
}
TEST_F(TestSmbFsBootstrapImpl, SaveRestorePassword) {
const std::vector<uint8_t> salt(
mojom::CredentialStorageOptions::kMinSaltLength, 'a');
const base::FilePath user_directory =
daemon_store_dir_.GetPath().Append(kAccountHash);
ASSERT_TRUE(base::CreateDirectory(user_directory));
EXPECT_TRUE(base::IsDirectoryEmpty(user_directory));
{
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kOk));
return fs;
});
EXPECT_CALL(mock_delegate_, OnPasswordFilePathSet(_))
.WillOnce([user_directory](const base::FilePath& path) {
EXPECT_TRUE(user_directory.IsParent(path));
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr),
fs_factory, &mock_delegate_,
daemon_store_dir_.GetPath());
boostrap_impl.Start(base::BindLambdaForTesting(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { EXPECT_TRUE(fs); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->workgroup = kWorkgroup;
mount_options->username = kUsername;
mount_options->password = MakePassword(kPassword);
mount_options->credential_storage_options =
mojom::CredentialStorageOptions::New(kAccountHash, salt);
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kOk, mount_error);
EXPECT_TRUE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
}
// There should be a file in the user's daemon-store directory.
EXPECT_FALSE(base::IsDirectoryEmpty(user_directory));
// Since the file's name and contents are obfuscated, don't check them
// directly. Instead, do another mount operation which uses the saved
// password.
{
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
EXPECT_EQ(options.credentials->workgroup, kWorkgroup);
EXPECT_EQ(options.credentials->username, kUsername);
EXPECT_EQ(options.credentials->password->GetRaw(),
std::string(kPassword));
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kOk));
return fs;
});
EXPECT_CALL(mock_delegate_, OnPasswordFilePathSet(_))
.WillOnce([user_directory](const base::FilePath& path) {
EXPECT_TRUE(user_directory.IsParent(path));
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr),
fs_factory, &mock_delegate_,
daemon_store_dir_.GetPath());
boostrap_impl.Start(base::BindLambdaForTesting(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { EXPECT_TRUE(fs); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->workgroup = kWorkgroup;
mount_options->username = kUsername;
// When there's no password field, implicitly restore the password from a
// file.
mount_options->credential_storage_options =
mojom::CredentialStorageOptions::New(kAccountHash, salt);
base::RunLoop run_loop;
ResetDelegate();
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kOk, mount_error);
EXPECT_TRUE(smbfs_ptr);
run_loop.Quit();
}));
run_loop.Run();
}
}
TEST_F(TestSmbFsBootstrapImpl, NoSavePasswordOnMountFailure) {
const std::vector<uint8_t> salt(
mojom::CredentialStorageOptions::kMinSaltLength, 'a');
const base::FilePath user_directory =
daemon_store_dir_.GetPath().Append(kAccountHash);
ASSERT_TRUE(base::CreateDirectory(user_directory));
EXPECT_TRUE(base::IsDirectoryEmpty(user_directory));
{
mojom::SmbFsBootstrapPtr boostrap_ptr;
auto fs_factory = base::BindLambdaForTesting(
[](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
std::unique_ptr<MockSmbFilesystem> fs =
std::make_unique<MockSmbFilesystem>();
EXPECT_CALL(*fs, EnsureConnected())
.WillOnce(Return(SmbFilesystem::ConnectError::kAccessDenied));
return fs;
});
SmbFsBootstrapImpl boostrap_impl(mojo::MakeRequest(&boostrap_ptr),
fs_factory, &mock_delegate_,
daemon_store_dir_.GetPath());
boostrap_impl.Start(base::BindLambdaForTesting(
[](std::unique_ptr<SmbFilesystem> fs, mojom::SmbFsRequest smbfs_request,
mojom::SmbFsDelegatePtr delegate_ptr) { EXPECT_TRUE(fs); }));
mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
mount_options->share_path = kSharePath;
mount_options->workgroup = kWorkgroup;
mount_options->username = kUsername;
mount_options->password = MakePassword(kPassword);
mount_options->credential_storage_options =
mojom::CredentialStorageOptions::New(kAccountHash, salt);
base::RunLoop run_loop;
boostrap_ptr->MountShare(
std::move(mount_options), std::move(smbfs_delegate_ptr_),
base::BindLambdaForTesting([&run_loop](mojom::MountError mount_error,
mojom::SmbFsPtr smbfs_ptr) {
EXPECT_EQ(mojom::MountError::kAccessDenied, mount_error);
run_loop.Quit();
}));
run_loop.Run();
}
// There should be no files in the user's daemon-store.
EXPECT_TRUE(base::IsDirectoryEmpty(user_directory));
}
} // namespace
} // namespace smbfs