blob: d6f841a16d25894ecfb82776418c4aa8a708813e [file] [log] [blame]
// Copyright 2018 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 "smbprovider/smbprovider_test_helper.h"
#include <algorithm>
#include <utility>
#include <gtest/gtest.h>
#include "smbprovider/mount_config.h"
#include "smbprovider/netbios_packet_parser.h"
#include "smbprovider/proto_bindings/directory_entry.pb.h"
#include "smbprovider/temp_file_manager.h"
#include <base/check.h>
#include <base/check_op.h>
namespace smbprovider {
namespace {
ProtoBlob SerializeProtoToBlobAndCheck(
const google::protobuf::MessageLite& proto) {
ProtoBlob proto_blob;
EXPECT_EQ(ERROR_OK, SerializeProtoToBlob(proto, &proto_blob));
return proto_blob;
}
} // namespace
MountOptionsProto CreateMountOptionsProto(const std::string& path,
const std::string& original_path,
const std::string& workgroup,
const std::string& username,
const std::string& account_hash,
bool skip_connect,
bool save_password,
bool restore_password,
const MountConfig& mount_config) {
MountOptionsProto mount_options;
mount_options.set_path(path);
mount_options.set_original_path(original_path);
mount_options.set_workgroup(workgroup);
mount_options.set_username(username);
mount_options.set_account_hash(account_hash);
mount_options.set_skip_connect(skip_connect);
mount_options.set_save_password(save_password);
mount_options.set_restore_password(restore_password);
std::unique_ptr<MountConfigProto> config =
std::make_unique<MountConfigProto>();
config->set_enable_ntlm(mount_config.enable_ntlm);
mount_options.set_allocated_mount_config(config.release());
return mount_options;
}
UnmountOptionsProto CreateUnmountOptionsProto(int32_t mount_id,
bool remove_password) {
UnmountOptionsProto unmount_options;
unmount_options.set_mount_id(mount_id);
unmount_options.set_remove_password(remove_password);
return unmount_options;
}
ReadDirectoryOptionsProto CreateReadDirectoryOptionsProto(
int32_t mount_id, const std::string& directory_path) {
ReadDirectoryOptionsProto read_directory_options;
read_directory_options.set_mount_id(mount_id);
read_directory_options.set_directory_path(directory_path);
return read_directory_options;
}
GetMetadataEntryOptionsProto CreateGetMetadataOptionsProto(
int32_t mount_id, const std::string& entry_path) {
GetMetadataEntryOptionsProto get_metadata_options;
get_metadata_options.set_mount_id(mount_id);
get_metadata_options.set_entry_path(entry_path);
return get_metadata_options;
}
OpenFileOptionsProto CreateOpenFileOptionsProto(int32_t mount_id,
const std::string& file_path,
bool writeable) {
OpenFileOptionsProto open_file_options;
open_file_options.set_mount_id(mount_id);
open_file_options.set_file_path(file_path);
open_file_options.set_writeable(writeable);
return open_file_options;
}
CloseFileOptionsProto CreateCloseFileOptionsProto(int32_t mount_id,
int32_t file_id) {
CloseFileOptionsProto close_file_options;
close_file_options.set_mount_id(mount_id);
close_file_options.set_file_id(file_id);
return close_file_options;
}
DeleteEntryOptionsProto CreateDeleteEntryOptionsProto(
int32_t mount_id, const std::string& entry_path, bool recursive) {
DeleteEntryOptionsProto delete_entry_options;
delete_entry_options.set_mount_id(mount_id);
delete_entry_options.set_entry_path(entry_path);
delete_entry_options.set_recursive(recursive);
return delete_entry_options;
}
ReadFileOptionsProto CreateReadFileOptionsProto(int32_t mount_id,
int32_t file_id,
int64_t offset,
int32_t length) {
ReadFileOptionsProto options;
options.set_mount_id(mount_id);
options.set_file_id(file_id);
options.set_offset(offset);
options.set_length(length);
return options;
}
CreateFileOptionsProto CreateCreateFileOptionsProto(
int32_t mount_id, const std::string& file_path) {
CreateFileOptionsProto options;
options.set_mount_id(mount_id);
options.set_file_path(file_path);
return options;
}
TruncateOptionsProto CreateTruncateOptionsProto(int32_t mount_id,
const std::string& file_path,
int64_t length) {
TruncateOptionsProto options;
options.set_mount_id(mount_id);
options.set_file_path(file_path);
options.set_length(length);
return options;
}
WriteFileOptionsProto CreateWriteFileOptionsProto(int32_t mount_id,
int32_t file_id,
int64_t offset,
int32_t length) {
WriteFileOptionsProto options;
options.set_mount_id(mount_id);
options.set_file_id(file_id);
options.set_offset(offset);
options.set_length(length);
return options;
}
CreateDirectoryOptionsProto CreateCreateDirectoryOptionsProto(
int32_t mount_id, const std::string& directory_path, bool recursive) {
CreateDirectoryOptionsProto options;
options.set_mount_id(mount_id);
options.set_directory_path(directory_path);
options.set_recursive(recursive);
return options;
}
MoveEntryOptionsProto CreateMoveEntryOptionsProto(
int32_t mount_id,
const std::string& source_path,
const std::string& target_path) {
MoveEntryOptionsProto options;
options.set_mount_id(mount_id);
options.set_source_path(source_path);
options.set_target_path(target_path);
return options;
}
CopyEntryOptionsProto CreateCopyEntryOptionsProto(
int32_t mount_id,
const std::string& source_path,
const std::string& target_path) {
CopyEntryOptionsProto options;
options.set_mount_id(mount_id);
options.set_source_path(source_path);
options.set_target_path(target_path);
return options;
}
GetDeleteListOptionsProto CreateGetDeleteListOptionsProto(
int32_t mount_id, const std::string& entry_path) {
GetDeleteListOptionsProto options;
options.set_mount_id(mount_id);
options.set_entry_path(entry_path);
return options;
}
GetSharesOptionsProto CreateGetSharesOptionsProto(
const std::string& server_url) {
GetSharesOptionsProto options;
options.set_server_url(server_url);
return options;
}
authpolicy::KerberosFiles CreateKerberosFilesProto(
const std::string& krb5cc, const std::string& krb5conf) {
authpolicy::KerberosFiles kerberos_files;
kerberos_files.set_krb5cc(krb5cc);
kerberos_files.set_krb5conf(krb5conf);
return kerberos_files;
}
UpdateMountCredentialsOptionsProto CreateUpdateMountCredentialsOptionsProto(
int32_t mount_id,
const std::string& workgroup,
const std::string& username) {
UpdateMountCredentialsOptionsProto update_options;
update_options.set_mount_id(mount_id);
update_options.set_workgroup(workgroup);
update_options.set_username(username);
return update_options;
}
UpdateSharePathOptionsProto CreateUpdateSharePathOptionsProto(
int32_t mount_id, const std::string& share_path) {
UpdateSharePathOptionsProto update_share_path_options;
update_share_path_options.set_mount_id(mount_id);
update_share_path_options.set_path(share_path);
return update_share_path_options;
}
ProtoBlob CreateMountOptionsBlob(const std::string& path) {
return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
path, "" /* original_path */, "" /* workgroup */, "" /* username */,
"" /* account_hash */, false /* skip_connect */,
false /* save_password */, false /* restore_password */,
MountConfig(true /* enable_ntlm */)));
}
ProtoBlob CreateMountOptionsBlob(const std::string& path,
const MountConfig& mount_config) {
return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
path, "" /* original_path */, "" /* workgroup */, "" /* username */,
"" /* account_hash */, false /* skip_connect */,
false /* save_password */, false /* restore_password */, mount_config));
}
ProtoBlob CreateMountOptionsBlob(const std::string& path,
const std::string& workgroup,
const std::string& username,
const MountConfig& mount_config) {
return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
path, "" /* original_path */, workgroup, username, "" /* account_hash */,
false /* skip_connect */, false /* save_password */,
false /* restore_password */, mount_config));
}
ProtoBlob CreateMountOptionsBlob(const std::string& path,
const std::string& original_path,
const std::string& workgroup,
const std::string& username,
const std::string& account_hash,
bool skip_connect,
bool save_password,
bool restore_password,
const MountConfig& mount_config) {
return SerializeProtoToBlobAndCheck(CreateMountOptionsProto(
path, original_path, workgroup, username, account_hash, skip_connect,
save_password, restore_password, mount_config));
}
ProtoBlob CreateUnmountOptionsBlob(int32_t mount_id, bool remove_password) {
return SerializeProtoToBlobAndCheck(
CreateUnmountOptionsProto(mount_id, remove_password));
}
ProtoBlob CreateReadDirectoryOptionsBlob(int32_t mount_id,
const std::string& directory_path) {
return SerializeProtoToBlobAndCheck(
CreateReadDirectoryOptionsProto(mount_id, directory_path));
}
ProtoBlob CreateGetMetadataOptionsBlob(int32_t mount_id,
const std::string& entry_path) {
ProtoBlob proto_blob;
return SerializeProtoToBlobAndCheck(
CreateGetMetadataOptionsProto(mount_id, entry_path));
}
ProtoBlob CreateOpenFileOptionsBlob(int32_t mount_id,
const std::string& file_path,
bool writeable) {
return SerializeProtoToBlobAndCheck(
CreateOpenFileOptionsProto(mount_id, file_path, writeable));
}
ProtoBlob CreateCloseFileOptionsBlob(int32_t mount_id, int32_t file_id) {
return SerializeProtoToBlobAndCheck(
CreateCloseFileOptionsProto(mount_id, file_id));
}
ProtoBlob CreateDeleteEntryOptionsBlob(int32_t mount_id,
const std::string& entry_path,
bool recursive) {
return SerializeProtoToBlobAndCheck(
CreateDeleteEntryOptionsProto(mount_id, entry_path, recursive));
}
ProtoBlob CreateReadFileOptionsBlob(int32_t mount_id,
int32_t file_id,
int64_t offset,
int32_t length) {
return SerializeProtoToBlobAndCheck(
CreateReadFileOptionsProto(mount_id, file_id, offset, length));
}
ProtoBlob CreateCreateFileOptionsBlob(int32_t mount_id,
const std::string& file_path) {
return SerializeProtoToBlobAndCheck(
CreateCreateFileOptionsProto(mount_id, file_path));
}
ProtoBlob CreateTruncateOptionsBlob(int32_t mount_id,
const std::string& file_path,
int64_t length) {
return SerializeProtoToBlobAndCheck(
CreateTruncateOptionsProto(mount_id, file_path, length));
}
ProtoBlob CreateWriteFileOptionsBlob(int32_t mount_id,
int32_t file_id,
int64_t offset,
int32_t length) {
return SerializeProtoToBlobAndCheck(
CreateWriteFileOptionsProto(mount_id, file_id, offset, length));
}
ProtoBlob CreateCreateDirectoryOptionsBlob(int32_t mount_id,
const std::string& directory_path,
bool recursive) {
return SerializeProtoToBlobAndCheck(
CreateCreateDirectoryOptionsProto(mount_id, directory_path, recursive));
}
ProtoBlob CreateMoveEntryOptionsBlob(int32_t mount_id,
const std::string& source_path,
const std::string& target_path) {
return SerializeProtoToBlobAndCheck(
CreateMoveEntryOptionsProto(mount_id, source_path, target_path));
}
ProtoBlob CreateCopyEntryOptionsBlob(int32_t mount_id,
const std::string& source_path,
const std::string& target_path) {
return SerializeProtoToBlobAndCheck(
CreateCopyEntryOptionsProto(mount_id, source_path, target_path));
}
ProtoBlob CreateGetDeleteListOptionsBlob(int32_t mount_id,
const std::string& entry_path) {
return SerializeProtoToBlobAndCheck(
CreateGetDeleteListOptionsProto(mount_id, entry_path));
}
ProtoBlob CreateGetSharesOptionsBlob(const std::string& server_url) {
return SerializeProtoToBlobAndCheck(CreateGetSharesOptionsProto(server_url));
}
ProtoBlob CreateUpdateMountCredentialsOptionsBlob(int32_t mount_id,
const std::string& workgroup,
const std::string& username) {
return SerializeProtoToBlobAndCheck(
CreateUpdateMountCredentialsOptionsProto(mount_id, workgroup, username));
}
ProtoBlob CreateUpdateSharePathOptionsBlob(int32_t mount_id,
const std::string& share_path) {
return SerializeProtoToBlobAndCheck(
CreateUpdateSharePathOptionsProto(mount_id, share_path));
}
base::ScopedFD WritePasswordToFile(TempFileManager* temp_manager,
const std::string& password) {
const size_t password_size = password.size();
std::vector<uint8_t> password_data(sizeof(password_size) + password.size());
// Write the password length in the first sizeof(size_t) bytes of the buffer.
std::memcpy(password_data.data(), &password_size, sizeof(password_size));
// Append |password| starting at the end of password_size.
std::memcpy(password_data.data() + sizeof(password_size), password.c_str(),
password.size());
return temp_manager->CreateTempFile(password_data);
}
std::string CreateKrb5ConfPath(const base::FilePath& temp_dir) {
return temp_dir.Append(kTestKrb5ConfName).value();
}
std::string CreateKrb5CCachePath(const base::FilePath& temp_dir) {
return temp_dir.Append(kTestCCacheName).value();
}
void ExpectFileEqual(const std::string& path,
const std::string expected_contents) {
const base::FilePath file_path(path);
std::string actual_contents;
EXPECT_TRUE(ReadFileToString(file_path, &actual_contents));
EXPECT_EQ(expected_contents, actual_contents);
}
void ExpectFileNotEqual(const std::string& path,
const std::string expected_contents) {
const base::FilePath file_path(path);
std::string actual_contents;
EXPECT_TRUE(ReadFileToString(file_path, &actual_contents));
EXPECT_NE(expected_contents, actual_contents);
}
void ExpectCredentialsEqual(MountManager* mount_manager,
int32_t mount_id,
const std::string& root_path,
const std::string& workgroup,
const std::string& username,
const std::string& password) {
DCHECK(mount_manager);
constexpr size_t kComparisonBufferSize = 256;
char workgroup_buffer[kComparisonBufferSize];
char username_buffer[kComparisonBufferSize];
char password_buffer[kComparisonBufferSize];
SambaInterface* samba_interface;
EXPECT_TRUE(mount_manager->GetSambaInterface(mount_id, &samba_interface));
const SambaInterface::SambaInterfaceId samba_interface_id =
samba_interface->GetSambaInterfaceId();
EXPECT_TRUE(mount_manager->GetAuthentication(
samba_interface_id, root_path, workgroup_buffer, kComparisonBufferSize,
username_buffer, kComparisonBufferSize, password_buffer,
kComparisonBufferSize));
EXPECT_EQ(std::string(workgroup_buffer), workgroup);
EXPECT_EQ(std::string(username_buffer), username);
EXPECT_EQ(std::string(password_buffer), password);
}
std::vector<uint8_t> CreateNetBiosResponsePacket(
const std::vector<std::vector<uint8_t>>& hostnames,
uint8_t name_length,
std::vector<uint8_t> name,
uint16_t transaction_id,
uint8_t response_type) {
// Build the prefix of the packet.
std::vector<uint8_t> packet = {0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// Set Transaction ID in Big Endian representation.
packet[0] = transaction_id >> 8;
packet[1] = transaction_id & 0xFF;
// Add the name section.
packet.push_back(name_length);
packet.insert(packet.end(), name.begin(), name.end());
// Add the next section
std::vector<uint8_t> middle_section = {0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00};
// Set the response_type.
middle_section[2] = response_type;
packet.insert(packet.end(), middle_section.begin(), middle_section.end());
// Set number of address list entries.
packet.push_back(hostnames.size());
// Add the address list entries.
for (const auto& hostname : hostnames) {
packet.insert(packet.end(), hostname.begin(), hostname.end());
}
return packet;
}
std::vector<uint8_t> CreateNetBiosResponsePacket(
const std::vector<std::vector<uint8_t>>& hostnames,
std::vector<uint8_t> name,
uint16_t transaction_id,
uint8_t response_type) {
return CreateNetBiosResponsePacket(hostnames, name.size(), name,
transaction_id, response_type);
}
std::vector<uint8_t> CreateValidNetBiosHostname(const std::string& hostname,
uint8_t type) {
DCHECK_LE(hostname.size(), netbios::kServerNameLength);
std::vector<uint8_t> hostname_bytes(netbios::kServerEntrySize);
std::copy(hostname.begin(), hostname.end(), hostname_bytes.begin());
// Fill the rest of the name with spaces.
std::fill(hostname_bytes.begin() + hostname.size(),
hostname_bytes.begin() + netbios::kServerNameLength, 0x20);
// Set the type.
hostname_bytes[15] = type;
// Set two nulls for the flags.
hostname_bytes[16] = 0x00;
hostname_bytes[17] = 0x00;
return hostname_bytes;
}
} // namespace smbprovider