// 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/mojo_session.h"

#include <unistd.h>

#include <utility>

#include <base/bind.h>
#include <base/logging.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <mojo/public/cpp/bindings/binding.h>

#include "smbfs/authpolicy_client.h"
#include "smbfs/fuse_session.h"
#include "smbfs/kerberos_artifact_synchronizer.h"
#include "smbfs/kerberos_client.h"
#include "smbfs/smb_filesystem.h"
#include "smbfs/smbfs.h"
#include "smbfs/smbfs_impl.h"

namespace smbfs {
namespace {

constexpr char kKerberosConfDir[] = ".krb";
constexpr char kKrb5ConfFile[] = "krb5.conf";
constexpr char kCCacheFile[] = "ccache";
constexpr char kKrbTraceFile[] = "krb_trace.txt";
constexpr char kDaemonStoreDirectory[] = "/run/daemon-store/smbfs";

}  // namespace

MojoSession::MojoSession(scoped_refptr<dbus::Bus> bus,
                         const base::FilePath& temp_dir,
                         fuse_chan* chan,
                         mojom::SmbFsBootstrapRequest bootstrap_request,
                         uid_t uid,
                         gid_t gid,
                         base::OnceClosure shutdown_callback)
    : bus_(std::move(bus)),
      temp_dir_(temp_dir),
      chan_(chan),
      uid_(uid),
      gid_(gid),
      shutdown_callback_(std::move(shutdown_callback)),
      bootstrap_impl_(std::make_unique<SmbFsBootstrapImpl>(
          std::move(bootstrap_request),
          base::BindRepeating(&MojoSession::CreateSmbFilesystem,
                              base::Unretained(this)),
          this,
          base::FilePath(kDaemonStoreDirectory))) {
  DCHECK(!temp_dir_.empty());
  DCHECK(chan_);
  DCHECK(shutdown_callback_);

  // Setup locations of Kerberos configuration files.
  base::File::Error error;
  bool success = base::CreateDirectoryAndGetError(
      temp_dir_.Append(kKerberosConfDir), &error);
  CHECK(success) << "Failed to create kerberos configuration directory: "
                 << base::File::ErrorToString(error);

  PCHECK(setenv("KRB5_CONFIG",
                KerberosConfFilePath(kKrb5ConfFile).value().c_str(),
                1 /* overwrite */) == 0);
  PCHECK(setenv("KRB5CCNAME", KerberosConfFilePath(kCCacheFile).value().c_str(),
                1 /* overwrite */) == 0);
  PCHECK(setenv("KRB5_TRACE",
                KerberosConfFilePath(kKrbTraceFile).value().c_str(),
                1 /* overwrite */) == 0);

  bootstrap_impl_->Start(base::BindOnce(&MojoSession::OnBootstrapComplete,
                                        base::Unretained(this)));
}

MojoSession::~MojoSession() = default;

base::FilePath MojoSession::KerberosConfFilePath(const std::string& file_name) {
  return temp_dir_.Append(kKerberosConfDir).Append(file_name);
}

void MojoSession::SetupKerberos(
    mojom::KerberosConfigPtr kerberos_config,
    base::OnceCallback<void(bool success)> callback) {
  DCHECK(!kerberos_sync_);
  DCHECK(kerberos_config);

  std::unique_ptr<KerberosArtifactClientInterface> client;
  switch (kerberos_config->source) {
    case mojom::KerberosConfig::Source::kActiveDirectory:
      client = std::make_unique<AuthPolicyClient>(bus_);
      break;
    case mojom::KerberosConfig::Source::kKerberos:
      client = std::make_unique<KerberosClient>(bus_);
      break;
  }

  DCHECK(client);
  kerberos_sync_ = std::make_unique<KerberosArtifactSynchronizer>(
      KerberosConfFilePath(kKrb5ConfFile), KerberosConfFilePath(kCCacheFile),
      kerberos_config->identity, std::move(client));
  kerberos_sync_->SetupKerberos(std::move(callback));
}

void MojoSession::OnPasswordFilePathSet(const base::FilePath& path) {
  password_file_path_ = path;
}

std::unique_ptr<SmbFilesystem> MojoSession::CreateSmbFilesystem(
    SmbFilesystem::Options options) {
  options.uid = uid_;
  options.gid = gid_;
  options.use_kerberos = kerberos_sync_.get();
  return std::make_unique<SmbFilesystem>(this, std::move(options));
}

void MojoSession::OnBootstrapComplete(std::unique_ptr<SmbFilesystem> fs,
                                      mojom::SmbFsRequest smbfs_request,
                                      mojom::SmbFsDelegatePtr delegate_ptr) {
  if (!fs) {
    LOG(ERROR) << "Connection error during Mojo bootstrap.";
    DoShutdown();
    return;
  }

  DCHECK(!fuse_session_);
  DCHECK(chan_);

  smbfs_impl_ = std::make_unique<SmbFsImpl>(
      fs->GetWeakPtr(), std::move(smbfs_request), password_file_path_);
  smbfs_delegate_ = std::move(delegate_ptr);
  smbfs_delegate_.set_connection_error_handler(
      base::BindOnce(&MojoSession::DoShutdown, base::Unretained(this)));

  fuse_session_ = std::make_unique<FuseSession>(std::move(fs), chan_);
  chan_ = nullptr;
  CHECK(fuse_session_->Start(
      base::BindOnce(&MojoSession::DoShutdown, base::Unretained(this))));
}

void MojoSession::DoShutdown() {
  if (!shutdown_callback_) {
    return;
  }

  std::move(shutdown_callback_).Run();
}

void MojoSession::RequestCredentials(RequestCredentialsCallback callback) {
  DCHECK(smbfs_delegate_);
  smbfs_delegate_->RequestCredentials(
      base::Bind(&MojoSession::OnRequestCredentialsDone, base::Unretained(this),
                 base::Passed(&callback)));
}

void MojoSession::OnRequestCredentialsDone(RequestCredentialsCallback callback,
                                           mojom::CredentialsPtr credentials) {
  if (!credentials) {
    std::move(callback).Run(nullptr);
    return;
  }

  std::unique_ptr<SmbCredential> smb_cred = std::make_unique<SmbCredential>(
      credentials->workgroup, credentials->username, nullptr);
  if (credentials->password) {
    smb_cred->password = std::move(credentials->password.value());
  }
  std::move(callback).Run(std::move(smb_cred));
}

}  // namespace smbfs
