// Copyright (c) 2013 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.

// A helper which provides methods to extract data from a pam_handle.

#include "chaps/pam_helper.h"

#include <security/pam_appl.h>
#include <security/pam_modules.h>

#include <vector>

#include <base/logging.h>
#include <chromeos/secure_blob.h>

#include "chaps/chaps_utility.h"

using std::string;
using std::vector;
using chromeos::SecureBlob;

namespace chaps {

namespace {

const char* kUserKey = "chaps_user_key";
const char* kPasswordKey = "chaps_password_key";

static void FreeUser(pam_handle_t *pam_handle, void *data,
                     int error_status) {
  if (data != NULL) {
    string* user = reinterpret_cast<string*>(data);
    delete user;
  }
}

static void FreePassword(pam_handle_t *pam_handle, void *data,
                         int error_status) {
  if (data != NULL) {
    SecureBlob* password = reinterpret_cast<SecureBlob*>(data);
    password->clear_contents();
    delete password;
  }
}

}  // namespace

PamHelper::~PamHelper() { }

bool PamHelper::GetPamUser(pam_handle_t* pam_handle, string* user) {
  const char* user_raw;
  int result;

  result = pam_get_user(pam_handle, &user_raw, NULL);
  if (result != PAM_SUCCESS) {
    LOG(ERROR) << "Could not get the pam user name: "
               << pam_strerror(pam_handle, result);
    return false;
  }

  *user = string(user_raw);
  // Note: user_raw is the actual data, so should not be overwritten or freed.
  return true;
}

bool PamHelper::GetPamPassword(pam_handle_t* pam_handle,
                               bool old_password,
                               SecureBlob* data) {
  const char* data_raw;
  int result;
  int pam_item_type;

  pam_item_type = old_password ? PAM_OLDAUTHTOK : PAM_AUTHTOK;

  result = pam_get_item(pam_handle, pam_item_type,
                        reinterpret_cast<const void **>(&data_raw));
  if (result != PAM_SUCCESS || data_raw == NULL) {
    // TODO(rmcilroy): Prompt for password if possible.
    LOG(WARNING) << "Could not get pam password: "
                 << pam_strerror(pam_handle, result);
    return false;
  }

  SecureBlob tmp(data_raw, strlen(data_raw));
  data->swap(tmp);

  // Note: data_raw is the actual data, so should not be overwritten or freed.
  return true;
}

bool PamHelper::SaveUserAndPassword(pam_handle_t* pam_handle,
                                    const string& user,
                                    const SecureBlob& password) {
  void* user_data = new string(user);
  if (pam_set_data(pam_handle, kUserKey, user_data, FreeUser) != PAM_SUCCESS) {
    LOG(ERROR) << "Could not save user name in PAM handle";
    return false;
  }

  void* password_data = new SecureBlob(password);
  if (pam_set_data(pam_handle, kPasswordKey, password_data, FreePassword) !=
      PAM_SUCCESS) {
    LOG(ERROR) << "Could not save password in PAM handle";
    return false;
  }

  return true;
}

bool PamHelper::RetrieveUserAndPassword(pam_handle_t* pam_handle,
                                        string* user,
                                        SecureBlob* password) {
  CHECK(user);
  CHECK(password);

  const void* user_data;
  if (pam_get_data(pam_handle, kUserKey, &user_data) != PAM_SUCCESS) {
    VLOG(1) << "Could not retrieve user name from PAM handle";
    return false;
  }
  *user = *reinterpret_cast<const string*>(user_data);

  const void* password_data;
  if (pam_get_data(pam_handle, kPasswordKey, &password_data) != PAM_SUCCESS) {
    LOG(INFO) << "Could not retrieve password from PAM handle";
    return false;
  }
  SecureBlob tmp(*reinterpret_cast<const SecureBlob*>(password_data));
  password->swap(tmp);

  return true;
}

bool PamHelper::PutEnvironmentVariable(pam_handle_t* pam_handle,
                                       const string& name,
                                       const string& value) {
  string env_var = name + "=" + value;
  return pam_putenv(pam_handle, env_var.c_str()) == PAM_SUCCESS;
}

bool PamHelper::GetEnvironmentVariable(pam_handle_t* pam_handle,
                                       const string& name,
                                       string* value) {
  CHECK(value);
  const char* value_raw = pam_getenv(pam_handle, name.c_str());
  if (value_raw == NULL || value_raw[0] == '\0')
    return false;
  *value = string(value_raw);
  return true;
}

}  // namespace chaps
