/* GIO - GLib Input, Output and Streaming Library
 *
 * Copyright (C) 2011 Collabora, Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Author: Stef Walter <stefw@collabora.co.uk>
 */

#include "config.h"
#include "glib.h"
#include "glibintl.h"

#include "gioenumtypes.h"
#include "gtlspassword.h"

#include <string.h>

/**
 * SECTION:gtlspassword
 * @title: GTlsPassword
 * @short_description: TLS Passwords for prompting
 * @include: gio/gio.h
 *
 * Holds a password used in TLS.
 */

/**
 * GTlsPassword:
 *
 * An abstract interface representing a password used in TLS. Often used in
 * user interaction such as unlocking a key storage token.
 *
 * Since: 2.30
 */

enum
{
  PROP_0,
  PROP_FLAGS,
  PROP_DESCRIPTION,
  PROP_WARNING
};

struct _GTlsPasswordPrivate
{
  guchar *value;
  gsize length;
  GDestroyNotify destroy;
  GTlsPasswordFlags flags;
  gchar *description;
  gchar *warning;
};

G_DEFINE_TYPE_WITH_PRIVATE (GTlsPassword, g_tls_password, G_TYPE_OBJECT)

static void
g_tls_password_init (GTlsPassword *password)
{
  password->priv = g_tls_password_get_instance_private (password);
}

static const guchar *
g_tls_password_real_get_value (GTlsPassword  *password,
                               gsize         *length)
{
  if (length)
    *length = password->priv->length;
  return password->priv->value;
}

static void
g_tls_password_real_set_value (GTlsPassword   *password,
                               guchar         *value,
                               gssize          length,
                               GDestroyNotify  destroy)
{
  if (password->priv->destroy)
      (password->priv->destroy) (password->priv->value);
  password->priv->destroy = NULL;
  password->priv->value = NULL;
  password->priv->length = 0;

  if (length < 0)
    length = strlen ((gchar*) value);

  password->priv->value = value;
  password->priv->length = length;
  password->priv->destroy = destroy;
}

static const gchar*
g_tls_password_real_get_default_warning (GTlsPassword  *password)
{
  GTlsPasswordFlags flags;

  flags = g_tls_password_get_flags (password);

  if (flags & G_TLS_PASSWORD_FINAL_TRY)
    return _("This is the last chance to enter the password correctly before your access is locked out.");
  if (flags & G_TLS_PASSWORD_MANY_TRIES)
    return _("Several password entered have been incorrect, and your access will be locked out after further failures.");
  if (flags & G_TLS_PASSWORD_RETRY)
    return _("The password entered is incorrect.");

  return NULL;
}

static void
g_tls_password_get_property (GObject    *object,
                             guint       prop_id,
                             GValue     *value,
                             GParamSpec *pspec)
{
  GTlsPassword *password = G_TLS_PASSWORD (object);

  switch (prop_id)
    {
    case PROP_FLAGS:
      g_value_set_flags (value, g_tls_password_get_flags (password));
      break;
    case PROP_WARNING:
      g_value_set_string (value, g_tls_password_get_warning (password));
      break;
    case PROP_DESCRIPTION:
      g_value_set_string (value, g_tls_password_get_description (password));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_tls_password_set_property (GObject      *object,
                             guint         prop_id,
                             const GValue *value,
                             GParamSpec   *pspec)
{
  GTlsPassword *password = G_TLS_PASSWORD (object);

  switch (prop_id)
    {
    case PROP_FLAGS:
      g_tls_password_set_flags (password, g_value_get_flags (value));
      break;
    case PROP_WARNING:
      g_tls_password_set_warning (password, g_value_get_string (value));
      break;
    case PROP_DESCRIPTION:
      g_tls_password_set_description (password, g_value_get_string (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
g_tls_password_finalize (GObject *object)
{
  GTlsPassword *password = G_TLS_PASSWORD (object);

  g_tls_password_real_set_value (password, NULL, 0, NULL);
  g_free (password->priv->warning);
  g_free (password->priv->description);

  G_OBJECT_CLASS (g_tls_password_parent_class)->finalize (object);
}

static void
g_tls_password_class_init (GTlsPasswordClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  klass->get_value = g_tls_password_real_get_value;
  klass->set_value = g_tls_password_real_set_value;
  klass->get_default_warning = g_tls_password_real_get_default_warning;

  gobject_class->get_property = g_tls_password_get_property;
  gobject_class->set_property = g_tls_password_set_property;
  gobject_class->finalize = g_tls_password_finalize;

  g_object_class_install_property (gobject_class, PROP_FLAGS,
				   g_param_spec_flags ("flags",
						       P_("Flags"),
						       P_("Flags about the password"),
						       G_TYPE_TLS_PASSWORD_FLAGS,
						       G_TLS_PASSWORD_NONE,
						       G_PARAM_READWRITE |
						       G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_DESCRIPTION,
				   g_param_spec_string ("description",
							P_("Description"),
							P_("Description of what the password is for"),
							"",
							G_PARAM_READWRITE |
							G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_WARNING,
				   g_param_spec_string ("warning",
							P_("Warning"),
							P_("Warning about the password"),
							"",
							G_PARAM_READWRITE |
							G_PARAM_STATIC_STRINGS));

}

/**
 * g_tls_password_new:
 * @flags: the password flags
 * @description: description of what the password is for
 *
 * Create a new #GTlsPassword object.
 *
 * Returns: (transfer full): The newly allocated password object
 */
GTlsPassword *
g_tls_password_new (GTlsPasswordFlags  flags,
                    const gchar       *description)
{
  return g_object_new (G_TYPE_TLS_PASSWORD,
                       "flags", flags,
                       "description", description,
                       NULL);
}

/**
 * g_tls_password_get_value:
 * @password: a #GTlsPassword object
 * @length: (allow-none): location to place the length of the password.
 *
 * Get the password value. If @length is not %NULL then it will be
 * filled in with the length of the password value. (Note that the
 * password value is not nul-terminated, so you can only pass %NULL
 * for @length in contexts where you know the password will have a
 * certain fixed length.)
 *
 * Returns: The password value (owned by the password object).
 *
 * Since: 2.30
 */
const guchar *
g_tls_password_get_value (GTlsPassword  *password,
                          gsize         *length)
{
  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
  return G_TLS_PASSWORD_GET_CLASS (password)->get_value (password, length);
}

/**
 * g_tls_password_set_value:
 * @password: a #GTlsPassword object
 * @value: the new password value
 * @length: the length of the password, or -1
 *
 * Set the value for this password. The @value will be copied by the password
 * object.
 *
 * Specify the @length, for a non-nul-terminated password. Pass -1 as
 * @length if using a nul-terminated password, and @length will be
 * calculated automatically. (Note that the terminating nul is not
 * considered part of the password in this case.)
 *
 * Since: 2.30
 */
void
g_tls_password_set_value (GTlsPassword  *password,
                          const guchar  *value,
                          gssize         length)
{
  g_return_if_fail (G_IS_TLS_PASSWORD (password));

  if (length < 0)
    length = strlen ((gchar *)value);

  g_tls_password_set_value_full (password, g_memdup (value, length), length, g_free);
}

/**
 * g_tls_password_set_value_full:
 * @password: a #GTlsPassword object
 * @value: the value for the password
 * @length: the length of the password, or -1
 * @destroy: (allow-none): a function to use to free the password.
 *
 * Provide the value for this password.
 *
 * The @value will be owned by the password object, and later freed using
 * the @destroy function callback.
 *
 * Specify the @length, for a non-nul-terminated password. Pass -1 as
 * @length if using a nul-terminated password, and @length will be
 * calculated automatically. (Note that the terminating nul is not
 * considered part of the password in this case.)
 *
 * Virtual: set_value
 * Since: 2.30
 */
void
g_tls_password_set_value_full (GTlsPassword   *password,
                               guchar         *value,
                               gssize          length,
                               GDestroyNotify  destroy)
{
  g_return_if_fail (G_IS_TLS_PASSWORD (password));
  G_TLS_PASSWORD_GET_CLASS (password)->set_value (password, value,
                                                  length, destroy);
}

/**
 * g_tls_password_get_flags:
 * @password: a #GTlsPassword object
 *
 * Get flags about the password.
 *
 * Return value: The flags about the password.
 *
 * Since: 2.30
 */
GTlsPasswordFlags
g_tls_password_get_flags (GTlsPassword *password)
{
  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_PASSWORD_NONE);
  return password->priv->flags;
}

/**
 * g_tls_password_set_flags:
 * @password: a #GTlsPassword object
 * @flags: The flags about the password
 *
 * Set flags about the password.
 *
 * Since: 2.30
 */
void
g_tls_password_set_flags (GTlsPassword      *password,
                          GTlsPasswordFlags  flags)
{
  g_return_if_fail (G_IS_TLS_PASSWORD (password));

  password->priv->flags = flags;

  g_object_notify (G_OBJECT (password), "flags");
}

/**
 * g_tls_password_get_description:
 * @password: a #GTlsPassword object
 *
 * Get a description string about what the password will be used for.
 *
 * Return value: The description of the password.
 *
 * Since: 2.30
 */
const gchar*
g_tls_password_get_description (GTlsPassword *password)
{
  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);
  return password->priv->description;
}

/**
 * g_tls_password_set_description:
 * @password: a #GTlsPassword object
 * @description: The description of the password
 *
 * Set a description string about what the password will be used for.
 *
 * Since: 2.30
 */
void
g_tls_password_set_description (GTlsPassword      *password,
                                const gchar       *description)
{
  gchar *copy;

  g_return_if_fail (G_IS_TLS_PASSWORD (password));

  copy = g_strdup (description);
  g_free (password->priv->description);
  password->priv->description = copy;

  g_object_notify (G_OBJECT (password), "description");
}

/**
 * g_tls_password_get_warning:
 * @password: a #GTlsPassword object
 *
 * Get a user readable translated warning. Usually this warning is a
 * representation of the password flags returned from
 * g_tls_password_get_flags().
 *
 * Return value: The warning.
 *
 * Since: 2.30
 */
const gchar *
g_tls_password_get_warning (GTlsPassword      *password)
{
  g_return_val_if_fail (G_IS_TLS_PASSWORD (password), NULL);

  if (password->priv->warning == NULL)
    return G_TLS_PASSWORD_GET_CLASS (password)->get_default_warning (password);

  return password->priv->warning;
}

/**
 * g_tls_password_set_warning:
 * @password: a #GTlsPassword object
 * @warning: The user readable warning
 *
 * Set a user readable translated warning. Usually this warning is a
 * representation of the password flags returned from
 * g_tls_password_get_flags().
 *
 * Since: 2.30
 */
void
g_tls_password_set_warning (GTlsPassword      *password,
                            const gchar       *warning)
{
  gchar *copy;

  g_return_if_fail (G_IS_TLS_PASSWORD (password));

  copy = g_strdup (warning);
  g_free (password->priv->warning);
  password->priv->warning = copy;

  g_object_notify (G_OBJECT (password), "warning");
}
