smbfs_host.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/smbfs/smbfs_host.h"
  5. #include <utility>
  6. #include "ash/components/disks/disk_mount_manager.h"
  7. #include "base/bind.h"
  8. #include "base/callback_helpers.h"
  9. #include "base/files/file_util.h"
  10. #include "base/logging.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "mojo/public/cpp/bindings/receiver.h"
  13. namespace smbfs {
  14. namespace {
  15. class SmbFsDelegateImpl : public mojom::SmbFsDelegate {
  16. public:
  17. SmbFsDelegateImpl(
  18. mojo::PendingReceiver<mojom::SmbFsDelegate> pending_receiver,
  19. base::OnceClosure disconnect_callback,
  20. SmbFsHost::Delegate* delegate)
  21. : receiver_(this, std::move(pending_receiver)), delegate_(delegate) {
  22. receiver_.set_disconnect_handler(std::move(disconnect_callback));
  23. }
  24. SmbFsDelegateImpl(const SmbFsDelegateImpl&) = delete;
  25. SmbFsDelegateImpl& operator=(const SmbFsDelegateImpl&) = delete;
  26. ~SmbFsDelegateImpl() override = default;
  27. // mojom::SmbFsDelegate overrides.
  28. void RequestCredentials(RequestCredentialsCallback callback) override {
  29. delegate_->RequestCredentials(
  30. base::BindOnce(&SmbFsDelegateImpl::OnRequestCredentialsDone,
  31. weak_factory_.GetWeakPtr(), std::move(callback)));
  32. }
  33. private:
  34. void OnRequestCredentialsDone(RequestCredentialsCallback callback,
  35. bool cancel,
  36. const std::string& username,
  37. const std::string& workgroup,
  38. const std::string& password) {
  39. if (cancel) {
  40. std::move(callback).Run(nullptr);
  41. return;
  42. }
  43. mojom::CredentialsPtr creds =
  44. mojom::Credentials::New(username, workgroup, nullptr);
  45. if (password.size() > mojom::Password::kMaxLength) {
  46. LOG(WARNING) << "smbfs password too long";
  47. } else if (!password.empty()) {
  48. // Create pipe and write password.
  49. base::ScopedFD pipe_read_end;
  50. base::ScopedFD pipe_write_end;
  51. CHECK(base::CreatePipe(&pipe_read_end, &pipe_write_end,
  52. true /* non_blocking */));
  53. CHECK(base::WriteFileDescriptor(pipe_write_end.get(), password));
  54. creds->password = mojom::Password::New(
  55. mojo::WrapPlatformHandle(
  56. mojo::PlatformHandle(std::move(pipe_read_end))),
  57. static_cast<int32_t>(password.size()));
  58. }
  59. std::move(callback).Run(std::move(creds));
  60. }
  61. mojo::Receiver<mojom::SmbFsDelegate> receiver_;
  62. SmbFsHost::Delegate* const delegate_;
  63. base::WeakPtrFactory<SmbFsDelegateImpl> weak_factory_{this};
  64. };
  65. } // namespace
  66. SmbFsHost::Delegate::~Delegate() = default;
  67. SmbFsHost::SmbFsHost(
  68. std::unique_ptr<ash::disks::MountPoint> mount_point,
  69. Delegate* delegate,
  70. mojo::Remote<mojom::SmbFs> smbfs_remote,
  71. mojo::PendingReceiver<mojom::SmbFsDelegate> delegate_receiver)
  72. : mount_point_(std::move(mount_point)),
  73. delegate_(delegate),
  74. smbfs_(std::move(smbfs_remote)),
  75. delegate_impl_(std::make_unique<SmbFsDelegateImpl>(
  76. std::move(delegate_receiver),
  77. base::BindOnce(&SmbFsHost::OnDisconnect, base::Unretained(this)),
  78. delegate)) {
  79. DCHECK(mount_point_);
  80. DCHECK(delegate);
  81. smbfs_.set_disconnect_handler(
  82. base::BindOnce(&SmbFsHost::OnDisconnect, base::Unretained(this)));
  83. }
  84. SmbFsHost::~SmbFsHost() = default;
  85. void SmbFsHost::Unmount(SmbFsHost::UnmountCallback callback) {
  86. mount_point_->Unmount(base::BindOnce(
  87. &SmbFsHost::OnUnmountDone, base::Unretained(this), std::move(callback)));
  88. }
  89. void SmbFsHost::OnUnmountDone(SmbFsHost::UnmountCallback callback,
  90. ash::MountError result) {
  91. LOG_IF(ERROR, result != ash::MountError::kNone)
  92. << "Could not unmount smbfs share: " << result;
  93. std::move(callback).Run(result);
  94. }
  95. void SmbFsHost::RemoveSavedCredentials(
  96. SmbFsHost::RemoveSavedCredentialsCallback callback) {
  97. smbfs_->RemoveSavedCredentials(
  98. base::BindOnce(&SmbFsHost::OnRemoveSavedCredentialsDone,
  99. base::Unretained(this), std::move(callback)));
  100. }
  101. void SmbFsHost::OnRemoveSavedCredentialsDone(
  102. SmbFsHost::RemoveSavedCredentialsCallback callback,
  103. bool success) {
  104. LOG_IF(ERROR, !success) << "Unable to remove saved password for smbfs";
  105. std::move(callback).Run(success);
  106. }
  107. void SmbFsHost::OnDisconnect() {
  108. // Ensure only one disconnection event occurs.
  109. smbfs_.reset();
  110. delegate_impl_.reset();
  111. // This may delete us.
  112. delegate_->OnDisconnected();
  113. }
  114. void SmbFsHost::DeleteRecursively(const base::FilePath& path,
  115. DeleteRecursivelyCallback callback) {
  116. smbfs_->DeleteRecursively(
  117. path, base::BindOnce(&SmbFsHost::OnDeleteRecursivelyDone,
  118. base::Unretained(this), std::move(callback)));
  119. }
  120. void SmbFsHost::OnDeleteRecursivelyDone(
  121. DeleteRecursivelyCallback callback,
  122. smbfs::mojom::DeleteRecursivelyError error) {
  123. base::File::Error file_error =
  124. error == smbfs::mojom::DeleteRecursivelyError::kOk
  125. ? base::File::FILE_OK
  126. : base::File::FILE_ERROR_FAILED;
  127. std::move(callback).Run(file_error);
  128. }
  129. } // namespace smbfs