/*
 * kwallet.cpp: KWallet provider for SVN_AUTH_CRED_*
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

/* ==================================================================== */



/*** Includes. ***/

#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <apr_pools.h>
#include <apr_strings.h>

#include <dbus/dbus.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QString>

#include <kaboutdata.h>
#include <klocalizedstring.h>
#include <kwallet.h>

#include "svn_auth.h"
#include "svn_config.h"
#include "svn_error.h"
#include "svn_hash.h"
#include "svn_io.h"
#include "svn_pools.h"
#include "svn_string.h"
#include "svn_version.h"

#include "private/svn_auth_private.h"

#include "svn_private_config.h"

#ifndef SVN_HAVE_KF5
#include <kcmdlineargs.h>
#include <kcomponentdata.h>
#endif

/*-----------------------------------------------------------------------*/
/* KWallet simple provider, puts passwords in KWallet                    */
/*-----------------------------------------------------------------------*/

static int q_argc = 1;
static char q_argv0[] = "svn"; // Build non-const char * from string constant
static char *q_argv[] = { q_argv0 };

static const char *
get_application_name(apr_hash_t *parameters,
                     apr_pool_t *pool)
{
  svn_config_t *config =
    static_cast<svn_config_t *> (apr_hash_get(parameters,
                                              SVN_AUTH_PARAM_CONFIG_CATEGORY_CONFIG,
                                              APR_HASH_KEY_STRING));
  svn_boolean_t svn_application_name_with_pid;
  svn_config_get_bool(config,
                      &svn_application_name_with_pid,
                      SVN_CONFIG_SECTION_AUTH,
                      SVN_CONFIG_OPTION_KWALLET_SVN_APPLICATION_NAME_WITH_PID,
                      FALSE);
  const char *svn_application_name;
  if (svn_application_name_with_pid)
    {
      svn_application_name = apr_psprintf(pool, "Subversion [%ld]", long(getpid()));
    }
  else
    {
      svn_application_name = "Subversion";
    }
  return svn_application_name;
}

static QString
get_wallet_name(apr_hash_t *parameters)
{
  svn_config_t *config =
    static_cast<svn_config_t *> (apr_hash_get(parameters,
                                              SVN_AUTH_PARAM_CONFIG_CATEGORY_CONFIG,
                                              APR_HASH_KEY_STRING));
  const char *wallet_name;
  svn_config_get(config,
                 &wallet_name,
                 SVN_CONFIG_SECTION_AUTH,
                 SVN_CONFIG_OPTION_KWALLET_WALLET,
                 "");
  if (strcmp(wallet_name, "") == 0)
    {
      return KWallet::Wallet::NetworkWallet();
    }
  else
    {
      return QString::fromUtf8(wallet_name);
    }
}

static WId
get_wid(void)
{
  WId wid = 1;
  const char *wid_env_string = getenv("WINDOWID");

  if (wid_env_string)
    {
      apr_int64_t wid_env;
      svn_error_t *err;

      err = svn_cstring_atoi64(&wid_env, wid_env_string);
      if (err)
        svn_error_clear(err);
      else
        wid = (WId)wid_env;
    }

  return wid;
}

/* Forward definition */
static apr_status_t
kwallet_terminate(void *data);

static KWallet::Wallet *
get_wallet(QString wallet_name,
           apr_hash_t *parameters)
{
  KWallet::Wallet *wallet =
    static_cast<KWallet::Wallet *> (svn_hash_gets(parameters,
                                                  "kwallet-wallet"));
  if (! wallet && ! svn_hash_gets(parameters, "kwallet-opening-failed"))
    {
      wallet = KWallet::Wallet::openWallet(wallet_name, get_wid(),
                                           KWallet::Wallet::Synchronous);

      if (wallet)
        {
          svn_hash_sets(parameters, "kwallet-wallet", wallet);

          apr_pool_cleanup_register(apr_hash_pool_get(parameters),
                                    parameters, kwallet_terminate,
                                    apr_pool_cleanup_null);

          svn_hash_sets(parameters, "kwallet-initialized", "");
        }
      else
        {
          svn_hash_sets(parameters, "kwallet-opening-failed", "");
        }
    }
  return wallet;
}

static apr_status_t
kwallet_terminate(void *data)
{
  apr_hash_t *parameters = static_cast<apr_hash_t *> (data);
  if (svn_hash_gets(parameters, "kwallet-initialized"))
    {
      KWallet::Wallet *wallet = get_wallet(NULL, parameters);
      delete wallet;
      svn_hash_sets(parameters, "kwallet-wallet", NULL);
      svn_hash_sets(parameters, "kwallet-initialized", NULL);
    }
  return APR_SUCCESS;
}

/* Implementation of svn_auth__password_get_t that retrieves
   the password from KWallet. */
static svn_error_t *
kwallet_password_get(svn_boolean_t *done,
                     const char **password,
                     apr_hash_t *creds,
                     const char *realmstring,
                     const char *username,
                     apr_hash_t *parameters,
                     svn_boolean_t non_interactive,
                     apr_pool_t *pool)
{
  QString wallet_name = get_wallet_name(parameters);

  *done = FALSE;

  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
    {
      return SVN_NO_ERROR;
    }

  if (non_interactive)
    {
      if (!KWallet::Wallet::isOpen(wallet_name))
        return SVN_NO_ERROR;

      /* There is a race here: the wallet was open just now, but will
         it still be open when we come to use it below? */
    }

  QCoreApplication *app;
  if (! qApp)
    {
      int argc = q_argc;
      app = new QCoreApplication(argc, q_argv);
    }

#if SVN_HAVE_KF5
  KLocalizedString::setApplicationDomain("subversion"); /* translation domain */

  /* componentName appears in KDE GUI prompts */
  KAboutData aboutData(QString("subversion"),            /* componentName */
                       i18n(get_application_name(parameters,
                                                 pool)), /* displayName */
                       QString(SVN_VER_NUMBER));
  KAboutData::setApplicationData(aboutData);
#else
  KCmdLineArgs::init(q_argc, q_argv,
                     get_application_name(parameters, pool),
                     "subversion",
                     ki18n(get_application_name(parameters, pool)),
                     SVN_VER_NUMBER,
                     ki18n("Version control system"),
                     KCmdLineArgs::CmdLineArgKDE);
  KComponentData component_data(KCmdLineArgs::aboutData());
#endif

  QString folder = QString::fromUtf8("Subversion");
  QString key =
    QString::fromUtf8(username) + "@" + QString::fromUtf8(realmstring);
  if (! KWallet::Wallet::keyDoesNotExist(wallet_name, folder, key))
    {
      KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
      if (wallet)
        {
          if (wallet->setFolder(folder))
            {
              QString q_password;
              if (wallet->readPassword(key, q_password) == 0)
                {
                  *password = apr_pstrmemdup(pool,
                                             q_password.toUtf8().data(),
                                             q_password.size());
                  *done = TRUE;
                }
            }
        }
    }

  return SVN_NO_ERROR;
}

/* Implementation of svn_auth__password_set_t that stores
   the password in KWallet. */
static svn_error_t *
kwallet_password_set(svn_boolean_t *done,
                     apr_hash_t *creds,
                     const char *realmstring,
                     const char *username,
                     const char *password,
                     apr_hash_t *parameters,
                     svn_boolean_t non_interactive,
                     apr_pool_t *pool)
{
  QString wallet_name = get_wallet_name(parameters);

  *done = FALSE;

  if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
    {
      return SVN_NO_ERROR;
    }

  if (non_interactive)
    {
      if (!KWallet::Wallet::isOpen(wallet_name))
        return SVN_NO_ERROR;

      /* There is a race here: the wallet was open just now, but will
         it still be open when we come to use it below? */
    }

  QCoreApplication *app;
  if (! qApp)
    {
      int argc = q_argc;
      app = new QCoreApplication(argc, q_argv);
    }

#if SVN_HAVE_KF5
  KLocalizedString::setApplicationDomain("subversion"); /* translation domain */

  /* componentName appears in KDE GUI prompts */
  KAboutData aboutData(QString("subversion"),            /* componentName */
                       i18n(get_application_name(parameters,
                                                 pool)), /* displayName */
                       QString(SVN_VER_NUMBER));
  KAboutData::setApplicationData(aboutData);
#else
  KCmdLineArgs::init(q_argc, q_argv,
                     get_application_name(parameters, pool),
                     "subversion",
                     ki18n(get_application_name(parameters, pool)),
                     SVN_VER_NUMBER,
                     ki18n("Version control system"),
                     KCmdLineArgs::CmdLineArgKDE);
  KComponentData component_data(KCmdLineArgs::aboutData());
#endif

  QString q_password = QString::fromUtf8(password);
  QString folder = QString::fromUtf8("Subversion");
  KWallet::Wallet *wallet = get_wallet(wallet_name, parameters);
  if (wallet)
    {
      if (! wallet->hasFolder(folder))
        {
          wallet->createFolder(folder);
        }
      if (wallet->setFolder(folder))
        {
          QString key = QString::fromUtf8(username) + "@"
            + QString::fromUtf8(realmstring);
          if (wallet->writePassword(key, q_password) == 0)
            {
              *done = TRUE;
            }
        }
    }

  return SVN_NO_ERROR;
}

/* Get cached encrypted credentials from the simple provider's cache. */
static svn_error_t *
kwallet_simple_first_creds(void **credentials,
                           void **iter_baton,
                           void *provider_baton,
                           apr_hash_t *parameters,
                           const char *realmstring,
                           apr_pool_t *pool)
{
  return svn_auth__simple_creds_cache_get(credentials,
                                          iter_baton,
                                          provider_baton,
                                          parameters,
                                          realmstring,
                                          kwallet_password_get,
                                          SVN_AUTH__KWALLET_PASSWORD_TYPE,
                                          pool);
}

/* Save encrypted credentials to the simple provider's cache. */
static svn_error_t *
kwallet_simple_save_creds(svn_boolean_t *saved,
                          void *credentials,
                          void *provider_baton,
                          apr_hash_t *parameters,
                          const char *realmstring,
                          apr_pool_t *pool)
{
  return svn_auth__simple_creds_cache_set(saved, credentials,
                                          provider_baton,
                                          parameters,
                                          realmstring,
                                          kwallet_password_set,
                                          SVN_AUTH__KWALLET_PASSWORD_TYPE,
                                          pool);
}

static const svn_auth_provider_t kwallet_simple_provider = {
  SVN_AUTH_CRED_SIMPLE,
  kwallet_simple_first_creds,
  NULL,
  kwallet_simple_save_creds
};

/* Public API */
extern "C" {
void
svn_auth_get_kwallet_simple_provider(svn_auth_provider_object_t **provider,
                                     apr_pool_t *pool)
{
  svn_auth_provider_object_t *po =
    static_cast<svn_auth_provider_object_t *> (apr_pcalloc(pool, sizeof(*po)));

  po->vtable = &kwallet_simple_provider;
  *provider = po;
}
}


/*-----------------------------------------------------------------------*/
/* KWallet SSL client certificate passphrase provider,                   */
/* puts passphrases in KWallet                                           */
/*-----------------------------------------------------------------------*/

/* Get cached encrypted credentials from the ssl client cert password
   provider's cache. */
static svn_error_t *
kwallet_ssl_client_cert_pw_first_creds(void **credentials,
                                       void **iter_baton,
                                       void *provider_baton,
                                       apr_hash_t *parameters,
                                       const char *realmstring,
                                       apr_pool_t *pool)
{
  return svn_auth__ssl_client_cert_pw_cache_get(credentials,
                                                iter_baton, provider_baton,
                                                parameters, realmstring,
                                                kwallet_password_get,
                                                SVN_AUTH__KWALLET_PASSWORD_TYPE,
                                                pool);
}

/* Save encrypted credentials to the ssl client cert password provider's
   cache. */
static svn_error_t *
kwallet_ssl_client_cert_pw_save_creds(svn_boolean_t *saved,
                                      void *credentials,
                                      void *provider_baton,
                                      apr_hash_t *parameters,
                                      const char *realmstring,
                                      apr_pool_t *pool)
{
  return svn_auth__ssl_client_cert_pw_cache_set(saved, credentials,
                                                provider_baton, parameters,
                                                realmstring,
                                                kwallet_password_set,
                                                SVN_AUTH__KWALLET_PASSWORD_TYPE,
                                                pool);
}

static const svn_auth_provider_t kwallet_ssl_client_cert_pw_provider = {
  SVN_AUTH_CRED_SSL_CLIENT_CERT_PW,
  kwallet_ssl_client_cert_pw_first_creds,
  NULL,
  kwallet_ssl_client_cert_pw_save_creds
};

/* Public API */
extern "C" {
void
svn_auth_get_kwallet_ssl_client_cert_pw_provider
    (svn_auth_provider_object_t **provider,
     apr_pool_t *pool)
{
  svn_auth_provider_object_t *po =
    static_cast<svn_auth_provider_object_t *> (apr_pcalloc(pool, sizeof(*po)));

  po->vtable = &kwallet_ssl_client_cert_pw_provider;
  *provider = po;
}
}
