Blame ui/gcr-gnupg-renderer.c

Packit b00eeb
/*
Packit b00eeb
 * Copyright (C) 2011 Collabora Ltd.
Packit b00eeb
 *
Packit b00eeb
 * This program is free software; you can redistribute it and/or modify
Packit b00eeb
 * it under the terms of the GNU Lesser General Public License as
Packit b00eeb
 * published by the Free Software Foundation; either version 2.1 of
Packit b00eeb
 * the License, or (at your option) any later version.
Packit b00eeb
 *
Packit b00eeb
 * This program is distributed in the hope that it will be useful, but
Packit b00eeb
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b00eeb
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit b00eeb
 * Lesser General Public License for more details.
Packit b00eeb
 *
Packit b00eeb
 * You should have received a copy of the GNU Lesser General Public
Packit b00eeb
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit b00eeb
 *
Packit b00eeb
 * Author: Stef Walter <stefw@collabora.co.uk>
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
#include "config.h"
Packit b00eeb
Packit b00eeb
#include "gcr/gcr-icons.h"
Packit b00eeb
#include "gcr/gcr-gnupg-records.h"
Packit b00eeb
#include "gcr/gcr-openpgp.h"
Packit b00eeb
#include "gcr/gcr-simple-certificate.h"
Packit b00eeb
#include "gcr/gcr-types.h"
Packit b00eeb
Packit b00eeb
#include "gcr-display-view.h"
Packit b00eeb
#include "gcr-gnupg-renderer.h"
Packit b00eeb
#include "gcr-renderer.h"
Packit b00eeb
Packit b00eeb
#include "gck/gck.h"
Packit b00eeb
Packit b00eeb
#include "egg/egg-hex.h"
Packit b00eeb
Packit b00eeb
#include <gdk/gdk.h>
Packit b00eeb
#include <glib/gi18n-lib.h>
Packit b00eeb
Packit b00eeb
#include <stdlib.h>
Packit b00eeb
Packit b00eeb
enum {
Packit b00eeb
	PROP_0,
Packit b00eeb
	PROP_RECORDS,
Packit b00eeb
	PROP_LABEL,
Packit b00eeb
	PROP_ATTRIBUTES
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
struct _GcrGnupgRendererPrivate {
Packit b00eeb
	GPtrArray *records;
Packit b00eeb
	GckAttributes *attrs;
Packit b00eeb
	gchar *label;
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
static void _gcr_gnupg_renderer_iface_init (GcrRendererIface *iface);
Packit b00eeb
Packit b00eeb
G_DEFINE_TYPE_WITH_CODE (GcrGnupgRenderer, _gcr_gnupg_renderer, G_TYPE_OBJECT,
Packit b00eeb
	G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, _gcr_gnupg_renderer_iface_init);
Packit b00eeb
);
Packit b00eeb
Packit b00eeb
/* -----------------------------------------------------------------------------
Packit b00eeb
 * INTERNAL
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
static gchar *
Packit b00eeb
calculate_label (GcrGnupgRenderer *self)
Packit b00eeb
{
Packit b00eeb
	gchar *userid;
Packit b00eeb
	gchar *label = NULL;
Packit b00eeb
Packit b00eeb
	if (self->pv->attrs) {
Packit b00eeb
		if (gck_attributes_find_string (self->pv->attrs, CKA_LABEL, &label))
Packit b00eeb
			return label;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	userid = _gcr_gnupg_records_get_user_id (self->pv->records);
Packit b00eeb
	if (userid != NULL) {
Packit b00eeb
		if (!_gcr_gnupg_records_parse_user_id (userid, &label, NULL, NULL))
Packit b00eeb
			label = NULL;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	if (label != NULL)
Packit b00eeb
		return label;
Packit b00eeb
Packit b00eeb
	if (self->pv->label)
Packit b00eeb
		return g_strdup (self->pv->label);
Packit b00eeb
Packit b00eeb
	return g_strdup (_("PGP Key"));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_init (GcrGnupgRenderer *self)
Packit b00eeb
{
Packit b00eeb
	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_GNUPG_RENDERER,
Packit b00eeb
	                                         GcrGnupgRendererPrivate));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_finalize (GObject *obj)
Packit b00eeb
{
Packit b00eeb
	GcrGnupgRenderer *self = GCR_GNUPG_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	gck_attributes_unref (self->pv->attrs);
Packit b00eeb
	g_free (self->pv->label);
Packit b00eeb
	if (self->pv->records)
Packit b00eeb
		g_ptr_array_unref (self->pv->records);
Packit b00eeb
Packit b00eeb
	G_OBJECT_CLASS (_gcr_gnupg_renderer_parent_class)->finalize (obj);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_set_property (GObject *obj,
Packit b00eeb
                                  guint prop_id,
Packit b00eeb
                                  const GValue *value,
Packit b00eeb
                                  GParamSpec *pspec)
Packit b00eeb
{
Packit b00eeb
	GcrGnupgRenderer *self = GCR_GNUPG_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	switch (prop_id) {
Packit b00eeb
	case PROP_RECORDS:
Packit b00eeb
		_gcr_gnupg_renderer_set_records (self, g_value_get_boxed (value));
Packit b00eeb
		break;
Packit b00eeb
	case PROP_LABEL:
Packit b00eeb
		g_free (self->pv->label);
Packit b00eeb
		self->pv->label = g_value_dup_string (value);
Packit b00eeb
		g_object_notify (obj, "label");
Packit b00eeb
		gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
		break;
Packit b00eeb
	case PROP_ATTRIBUTES:
Packit b00eeb
		_gcr_gnupg_renderer_set_attributes (self, g_value_get_boxed (value));
Packit b00eeb
		break;
Packit b00eeb
	default:
Packit b00eeb
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
Packit b00eeb
		break;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_get_property (GObject *obj,
Packit b00eeb
                                  guint prop_id,
Packit b00eeb
                                  GValue *value,
Packit b00eeb
                                  GParamSpec *pspec)
Packit b00eeb
{
Packit b00eeb
	GcrGnupgRenderer *self = GCR_GNUPG_RENDERER (obj);
Packit b00eeb
Packit b00eeb
	switch (prop_id) {
Packit b00eeb
	case PROP_RECORDS:
Packit b00eeb
		g_value_set_object (value, self->pv->records);
Packit b00eeb
		break;
Packit b00eeb
	case PROP_LABEL:
Packit b00eeb
		g_value_take_string (value, calculate_label (self));
Packit b00eeb
		break;
Packit b00eeb
	case PROP_ATTRIBUTES:
Packit b00eeb
		g_value_set_boxed (value, self->pv->attrs);
Packit b00eeb
		break;
Packit b00eeb
	default:
Packit b00eeb
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
Packit b00eeb
		break;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_class_init (GcrGnupgRendererClass *klass)
Packit b00eeb
{
Packit b00eeb
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
Packit b00eeb
	_gcr_gnupg_renderer_parent_class = g_type_class_peek_parent (klass);
Packit b00eeb
	g_type_class_add_private (klass, sizeof (GcrGnupgRendererPrivate));
Packit b00eeb
Packit b00eeb
	gobject_class->finalize = _gcr_gnupg_renderer_finalize;
Packit b00eeb
	gobject_class->set_property = _gcr_gnupg_renderer_set_property;
Packit b00eeb
	gobject_class->get_property = _gcr_gnupg_renderer_get_property;
Packit b00eeb
Packit b00eeb
	g_object_class_install_property (gobject_class, PROP_RECORDS,
Packit b00eeb
	           g_param_spec_boxed ("records", "Records", "Gnupg records to display",
Packit b00eeb
	                               G_TYPE_PTR_ARRAY, G_PARAM_READWRITE));
Packit b00eeb
Packit b00eeb
	g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
Packit b00eeb
	           g_param_spec_boxed ("attributes", "Attributes", "Certificate pkcs11 attributes",
Packit b00eeb
	                               GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));
Packit b00eeb
Packit b00eeb
	g_object_class_install_property (gobject_class, PROP_LABEL,
Packit b00eeb
	           g_param_spec_string ("label", "Label", "Certificate Label",
Packit b00eeb
	                                "", G_PARAM_READWRITE));
Packit b00eeb
Packit b00eeb
	/* Register this as a renderer which can be loaded */
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_GNUPG_RECORDS);
Packit b00eeb
	gcr_renderer_register (GCR_TYPE_GNUPG_RENDERER, gck_builder_end (&builder));
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const gchar *
Packit b00eeb
name_for_algo (guint algo)
Packit b00eeb
{
Packit b00eeb
	switch (algo)
Packit b00eeb
	{
Packit b00eeb
	case GCR_OPENPGP_ALGO_RSA:
Packit b00eeb
	case GCR_OPENPGP_ALGO_RSA_E:
Packit b00eeb
	case GCR_OPENPGP_ALGO_RSA_S:
Packit b00eeb
		return _("RSA");
Packit b00eeb
	case GCR_OPENPGP_ALGO_ELG_E:
Packit b00eeb
		return _("Elgamal");
Packit b00eeb
	case GCR_OPENPGP_ALGO_DSA:
Packit b00eeb
		return _("DSA");
Packit b00eeb
	default:
Packit b00eeb
		return NULL;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const gchar *
Packit b00eeb
capability_for_code (gchar code)
Packit b00eeb
{
Packit b00eeb
	switch (code) {
Packit b00eeb
	case 'e': case 'E':
Packit b00eeb
		return _("Encrypt");
Packit b00eeb
	case 's': case 'S':
Packit b00eeb
		return _("Sign");
Packit b00eeb
	case 'c': case 'C':
Packit b00eeb
		return _("Certify");
Packit b00eeb
	case 'a': case 'A':
Packit b00eeb
		return _("Authenticate");
Packit b00eeb
	case 'D':
Packit b00eeb
		return C_("capability", "Disabled");
Packit b00eeb
	default:
Packit b00eeb
		return NULL;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gchar *
Packit b00eeb
capabilities_for_codes (const gchar *codes)
Packit b00eeb
{
Packit b00eeb
	const gchar *cap;
Packit b00eeb
	GString *result;
Packit b00eeb
	guint i;
Packit b00eeb
Packit b00eeb
	result = g_string_new ("");
Packit b00eeb
	for (i = 0; codes[i] != 0; i++) {
Packit b00eeb
		if (result->len)
Packit b00eeb
			g_string_append_unichar (result, GCR_DISPLAY_VIEW_LINE_BREAK);
Packit b00eeb
		cap = capability_for_code (codes[i]);
Packit b00eeb
		if (cap != NULL)
Packit b00eeb
			g_string_append (result, cap);
Packit b00eeb
		else
Packit b00eeb
			g_string_append_c (result, codes[i]);
Packit b00eeb
	}
Packit b00eeb
	return g_string_free (result, FALSE);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const gchar *
Packit b00eeb
status_for_code (gchar code)
Packit b00eeb
{
Packit b00eeb
	switch (code) {
Packit b00eeb
	case 'o':
Packit b00eeb
		return _("Unknown");
Packit b00eeb
	case 'i':
Packit b00eeb
		return _("Invalid");
Packit b00eeb
	case 'd':
Packit b00eeb
		return C_("ownertrust", "Disabled");
Packit b00eeb
	case 'r':
Packit b00eeb
		return _("Revoked");
Packit b00eeb
	case 'e':
Packit b00eeb
		return _("Expired");
Packit b00eeb
	case 'q': case '-':
Packit b00eeb
		return _("Undefined trust");
Packit b00eeb
	case 'n':
Packit b00eeb
		return _("Distrusted");
Packit b00eeb
	case 'm':
Packit b00eeb
		return _("Marginally trusted");
Packit b00eeb
	case 'f':
Packit b00eeb
		return _("Fully trusted");
Packit b00eeb
	case 'u':
Packit b00eeb
		return _("Ultimately trusted");
Packit b00eeb
	default:
Packit b00eeb
		return NULL;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const gchar *
Packit b00eeb
message_for_code (gchar code,
Packit b00eeb
                  GtkMessageType *message_type)
Packit b00eeb
{
Packit b00eeb
	*message_type = GTK_MESSAGE_OTHER;
Packit b00eeb
	switch (code) {
Packit b00eeb
	case 'o':
Packit b00eeb
		*message_type = GTK_MESSAGE_QUESTION;
Packit b00eeb
		return _("The information in this key has not yet been verified");
Packit b00eeb
	case 'i':
Packit b00eeb
		*message_type = GTK_MESSAGE_ERROR;
Packit b00eeb
		return _("This key is invalid");
Packit b00eeb
	case 'd':
Packit b00eeb
		*message_type = GTK_MESSAGE_WARNING;
Packit b00eeb
		return _("This key has been disabled");
Packit b00eeb
	case 'r':
Packit b00eeb
		*message_type = GTK_MESSAGE_ERROR;
Packit b00eeb
		return _("This key has been revoked");
Packit b00eeb
	case 'e':
Packit b00eeb
		*message_type = GTK_MESSAGE_ERROR;
Packit b00eeb
		return _("This key has expired");
Packit b00eeb
	case 'q': case '-':
Packit b00eeb
		return NULL;
Packit b00eeb
	case 'n':
Packit b00eeb
		*message_type = GTK_MESSAGE_WARNING;
Packit b00eeb
		return _("This key is distrusted");
Packit b00eeb
	case 'm':
Packit b00eeb
		*message_type = GTK_MESSAGE_OTHER;
Packit b00eeb
		return _("This key is marginally trusted");
Packit b00eeb
	case 'f':
Packit b00eeb
		*message_type = GTK_MESSAGE_OTHER;
Packit b00eeb
		return _("This key is fully trusted");
Packit b00eeb
	case 'u':
Packit b00eeb
		*message_type = GTK_MESSAGE_OTHER;
Packit b00eeb
		return _("This key is ultimately trusted");
Packit b00eeb
	default:
Packit b00eeb
		return NULL;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_key_record (GcrGnupgRenderer *self,
Packit b00eeb
                   GcrDisplayView *view,
Packit b00eeb
                   GcrRecord *record,
Packit b00eeb
                   const gchar *title)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	const gchar *value;
Packit b00eeb
	gchar *display;
Packit b00eeb
	GDateTime *date;
Packit b00eeb
	gchar code;
Packit b00eeb
	guint algo;
Packit b00eeb
	guint bits;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, title);
Packit b00eeb
Packit b00eeb
	/* Key ID */
Packit b00eeb
	value = _gcr_record_get_raw (record, GCR_RECORD_KEY_KEYID);
Packit b00eeb
	if (value != NULL)
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Key ID"), value, TRUE);
Packit b00eeb
Packit b00eeb
	/* Algorithm */
Packit b00eeb
	if (_gcr_record_get_uint (record, GCR_RECORD_KEY_ALGO, &algo)) {
Packit b00eeb
		display = NULL;
Packit b00eeb
		value = name_for_algo (algo);
Packit b00eeb
		if (value == NULL)
Packit b00eeb
			value = display = g_strdup_printf ("%u", algo);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Algorithm"), value, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Key Size */
Packit b00eeb
	if (_gcr_record_get_uint (record, GCR_RECORD_KEY_BITS, &bits)) {
Packit b00eeb
		display = g_strdup_printf ("%u", bits);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Key Size"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Created */
Packit b00eeb
	date = _gcr_record_get_date (record, GCR_RECORD_KEY_TIMESTAMP);
Packit b00eeb
	if (date != NULL) {
Packit b00eeb
		display = g_date_time_format (date, "%x");
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Created"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
		g_date_time_unref (date);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Expiry */
Packit b00eeb
	date = _gcr_record_get_date (record, GCR_RECORD_KEY_EXPIRY);
Packit b00eeb
	if (date != NULL) {
Packit b00eeb
		display = g_date_time_format (date, "%x");
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Expiry"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
		g_date_time_unref (date);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Capabilities */
Packit b00eeb
	value = _gcr_record_get_raw (record, GCR_RECORD_PUB_CAPS);
Packit b00eeb
	if (value != NULL && value[0] != '\0') {
Packit b00eeb
		display = capabilities_for_codes (value);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Capabilities"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Owner Trust */
Packit b00eeb
	code = _gcr_record_get_char (record, GCR_RECORD_KEY_OWNERTRUST);
Packit b00eeb
	if (code != 0) {
Packit b00eeb
		display = NULL;
Packit b00eeb
		value = status_for_code (code);
Packit b00eeb
		if (value == NULL) {
Packit b00eeb
			value = display = g_new0 (gchar, 2);
Packit b00eeb
			display[0] = code;
Packit b00eeb
		}
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Owner trust"), value, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_uid_record (GcrGnupgRenderer *self,
Packit b00eeb
                   GcrDisplayView *view,
Packit b00eeb
                   GcrRecord *record)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	gchar *userid;
Packit b00eeb
	gchar *name;
Packit b00eeb
	gchar *comment;
Packit b00eeb
	gchar *email;
Packit b00eeb
	GDateTime *date;
Packit b00eeb
	gchar *display;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("User ID"));
Packit b00eeb
Packit b00eeb
	userid = _gcr_record_get_string (record, GCR_RECORD_UID_USERID);
Packit b00eeb
	if (userid == NULL) {
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Value"), _("Unknown"), FALSE);
Packit b00eeb
		return;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	if (_gcr_gnupg_records_parse_user_id (userid, &name, &email, &comment)) {
Packit b00eeb
		if (name != NULL)
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, _("Name"), name, FALSE);
Packit b00eeb
		g_free (name);
Packit b00eeb
		if (email != NULL)
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, _("Email"), email, FALSE);
Packit b00eeb
		g_free (email);
Packit b00eeb
		if (comment != NULL)
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, _("Comment"), comment, FALSE);
Packit b00eeb
		g_free (comment);
Packit b00eeb
Packit b00eeb
	/* Unparseable user id */
Packit b00eeb
	} else {
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Value"), userid, FALSE);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Created */
Packit b00eeb
	date = _gcr_record_get_date (record, GCR_RECORD_UID_TIMESTAMP);
Packit b00eeb
	if (date != NULL) {
Packit b00eeb
		display = g_date_time_format (date, "%x");
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Created"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
		g_date_time_unref (date);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Expiry */
Packit b00eeb
	date = _gcr_record_get_date (record, GCR_RECORD_UID_EXPIRY);
Packit b00eeb
	if (date != NULL) {
Packit b00eeb
		display = g_date_time_format (date, "%x");
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Expiry"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
		g_date_time_unref (date);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	g_free (userid);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_uat_record (GcrGnupgRenderer *self,
Packit b00eeb
                   GcrDisplayView *view,
Packit b00eeb
                   GcrRecord *record)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	gchar **parts;
Packit b00eeb
	gchar *display;
Packit b00eeb
	const gchar *value;
Packit b00eeb
	GDateTime *date;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("User Attribute"));
Packit b00eeb
Packit b00eeb
	/* Size */
Packit b00eeb
	value = _gcr_record_get_raw (record, GCR_RECORD_UAT_COUNT_SIZE);
Packit b00eeb
	if (value != NULL) {
Packit b00eeb
		parts = g_strsplit (value, " ", 2);
Packit b00eeb
		if (parts && parts[0] && parts[1])
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, _("Size"), parts[1], FALSE);
Packit b00eeb
		g_strfreev (parts);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Created */
Packit b00eeb
	date = _gcr_record_get_date (record, GCR_RECORD_KEY_TIMESTAMP);
Packit b00eeb
	if (date != NULL) {
Packit b00eeb
		display = g_date_time_format (date, "%x");
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Created"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
		g_date_time_unref (date);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Expiry */
Packit b00eeb
	date = _gcr_record_get_date (record, GCR_RECORD_KEY_EXPIRY);
Packit b00eeb
	if (date != NULL) {
Packit b00eeb
		display = g_date_time_format (date, "%x");
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Expiry"), display, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
		g_date_time_unref (date);
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static const gchar *
Packit b00eeb
signature_klass_string (const gchar *klass)
Packit b00eeb
{
Packit b00eeb
	char *end;
Packit b00eeb
	guint val;
Packit b00eeb
Packit b00eeb
	val = strtoul (klass, &end, 16);
Packit b00eeb
	if (end != klass + 2)
Packit b00eeb
		return NULL;
Packit b00eeb
Packit b00eeb
	switch (val) {
Packit b00eeb
	case 0x00:
Packit b00eeb
		return _("Signature of a binary document");
Packit b00eeb
	case 0x01:
Packit b00eeb
		return _("Signature of a canonical text document");
Packit b00eeb
	case 0x02:
Packit b00eeb
		return _("Standalone signature");
Packit b00eeb
	case 0x10:
Packit b00eeb
		return _("Generic certification of key");
Packit b00eeb
	case 0x11:
Packit b00eeb
		return _("Persona certification of key");
Packit b00eeb
	case 0x12:
Packit b00eeb
		return _("Casual certification of key");
Packit b00eeb
	case 0x13:
Packit b00eeb
		return _("Positive certification of key");
Packit b00eeb
	case 0x18:
Packit b00eeb
		return _("Subkey binding signature");
Packit b00eeb
	case 0x19:
Packit b00eeb
		return _("Primary key binding signature");
Packit b00eeb
	case 0x1F:
Packit b00eeb
		return _("Signature directly on key");
Packit b00eeb
	case 0x20:
Packit b00eeb
		return _("Key revocation signature");
Packit b00eeb
	case 0x28:
Packit b00eeb
		return _("Subkey revocation signature");
Packit b00eeb
	case 0x30:
Packit b00eeb
		return _("Certification revocation signature");
Packit b00eeb
	case 0x40:
Packit b00eeb
		return _("Timestamp signature");
Packit b00eeb
	case 0x50:
Packit b00eeb
		return _("Third-party confirmation signature");
Packit b00eeb
	default:
Packit b00eeb
		return NULL;
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_sig_record (GcrGnupgRenderer *self,
Packit b00eeb
                   GcrDisplayView *view,
Packit b00eeb
                   GcrRecord *record,
Packit b00eeb
                   const gchar *keyid)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	const gchar *sigid;
Packit b00eeb
	gchar *display;
Packit b00eeb
	const gchar *value;
Packit b00eeb
	const gchar *klass;
Packit b00eeb
	guint algo;
Packit b00eeb
Packit b00eeb
	/* Hide self-signatures. There's so many of them */
Packit b00eeb
	sigid = _gcr_record_get_raw (record, GCR_RECORD_SIG_KEYID);
Packit b00eeb
	if (sigid && keyid && g_str_equal (sigid, keyid))
Packit b00eeb
		return;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Signature"));
Packit b00eeb
Packit b00eeb
	/* Key ID */
Packit b00eeb
	if (sigid != NULL)
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Key ID"), sigid, TRUE);
Packit b00eeb
Packit b00eeb
	/* Algorithm */
Packit b00eeb
	if (_gcr_record_get_uint (record, GCR_RECORD_SIG_ALGO, &algo)) {
Packit b00eeb
		display = NULL;
Packit b00eeb
		value = name_for_algo (algo);
Packit b00eeb
		if (value == NULL)
Packit b00eeb
			value = display = g_strdup_printf ("%u", algo);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Algorithm"), value, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* User ID */
Packit b00eeb
	display = _gcr_record_get_string (record, GCR_RECORD_SIG_USERID);
Packit b00eeb
	if (display != NULL)
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("User ID"), display, FALSE);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	/* Signature class */
Packit b00eeb
	klass = _gcr_record_get_raw (record, GCR_RECORD_SIG_CLASS);
Packit b00eeb
	if (klass != NULL) {
Packit b00eeb
		value = NULL;
Packit b00eeb
		if (strlen (klass) >= 2) {
Packit b00eeb
			value = signature_klass_string (klass);
Packit b00eeb
			if (value != NULL) {
Packit b00eeb
				_gcr_display_view_append_value (view, renderer, _("Class"), value, FALSE);
Packit b00eeb
				if (klass[2] == 'l')
Packit b00eeb
					_gcr_display_view_append_value (view, renderer, _("Type"), _("Local only"), FALSE);
Packit b00eeb
				else if (klass[2] == 'x')
Packit b00eeb
					_gcr_display_view_append_value (view, renderer, _("Type"), _("Exportable"), FALSE);
Packit b00eeb
			}
Packit b00eeb
		}
Packit b00eeb
		if (value == NULL)
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, _("Class"), klass, FALSE);
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_rvk_record (GcrGnupgRenderer *self,
Packit b00eeb
                   GcrDisplayView *view,
Packit b00eeb
                   GcrRecord *record)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	const gchar *value;
Packit b00eeb
	gchar *display;
Packit b00eeb
	guint algo;
Packit b00eeb
Packit b00eeb
	_gcr_display_view_append_heading (view, renderer, _("Revocation Key"));
Packit b00eeb
Packit b00eeb
	/* Algorithm */
Packit b00eeb
	if (_gcr_record_get_uint (record, GCR_RECORD_RVK_ALGO, &algo)) {
Packit b00eeb
		display = NULL;
Packit b00eeb
		value = name_for_algo (algo);
Packit b00eeb
		if (value == NULL)
Packit b00eeb
			value = display = g_strdup_printf ("%u", algo);
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Algorithm"), value, FALSE);
Packit b00eeb
		g_free (display);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	value = _gcr_record_get_raw (record, GCR_RECORD_RVK_FINGERPRINT);
Packit b00eeb
	if (value != NULL)
Packit b00eeb
		_gcr_display_view_append_value (view, renderer, _("Fingerprint"), value, TRUE);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
append_fpr_record (GcrGnupgRenderer *self,
Packit b00eeb
                   GcrDisplayView *view,
Packit b00eeb
                   GcrRecord *record,
Packit b00eeb
                   GQuark last_schema)
Packit b00eeb
{
Packit b00eeb
	GcrRenderer *renderer = GCR_RENDERER (self);
Packit b00eeb
	const gchar *value;
Packit b00eeb
	gpointer raw;
Packit b00eeb
	gsize n_raw;
Packit b00eeb
Packit b00eeb
	if (last_schema != GCR_RECORD_SCHEMA_PUB &&
Packit b00eeb
	    last_schema != GCR_RECORD_SCHEMA_SUB &&
Packit b00eeb
	    last_schema != GCR_RECORD_SCHEMA_SEC &&
Packit b00eeb
	    last_schema != GCR_RECORD_SCHEMA_SSB)
Packit b00eeb
		return;
Packit b00eeb
Packit b00eeb
	value = _gcr_record_get_raw (record, GCR_RECORD_FPR_FINGERPRINT);
Packit b00eeb
	if (value != NULL) {
Packit b00eeb
		raw = egg_hex_decode (value, -1, &n_raw);
Packit b00eeb
		if (raw != NULL)
Packit b00eeb
			_gcr_display_view_append_hex (view, renderer, _("Fingerprint"), raw, n_raw);
Packit b00eeb
		else
Packit b00eeb
			_gcr_display_view_append_value (view, renderer, _("Fingerprint"), value, TRUE);
Packit b00eeb
		g_free (raw);
Packit b00eeb
	}
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_render (GcrRenderer *renderer,
Packit b00eeb
                            GcrViewer *viewer)
Packit b00eeb
{
Packit b00eeb
	GtkMessageType message_type;
Packit b00eeb
	GcrGnupgRenderer *self;
Packit b00eeb
	GcrDisplayView *view;
Packit b00eeb
	GDateTime *date;
Packit b00eeb
	const gchar *value;
Packit b00eeb
	gchar *display;
Packit b00eeb
	gchar *userid;
Packit b00eeb
	gchar *email;
Packit b00eeb
	gchar *comment;
Packit b00eeb
	GIcon *icon;
Packit b00eeb
	GQuark schema;
Packit b00eeb
	GQuark last_schema;
Packit b00eeb
	gchar code;
Packit b00eeb
	guint i;
Packit b00eeb
Packit b00eeb
	self = GCR_GNUPG_RENDERER (renderer);
Packit b00eeb
Packit b00eeb
	if (GCR_IS_DISPLAY_VIEW (viewer)) {
Packit b00eeb
		view = GCR_DISPLAY_VIEW (viewer);
Packit b00eeb
Packit b00eeb
	} else {
Packit b00eeb
		g_warning ("GcrGnupgRenderer only works with internal specific "
Packit b00eeb
		           "GcrViewer returned by gcr_viewer_new().");
Packit b00eeb
		return;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_display_view_begin (view, renderer);
Packit b00eeb
Packit b00eeb
	if (self->pv->records == NULL || self->pv->records->len == 0) {
Packit b00eeb
		_gcr_display_view_end (view, renderer);
Packit b00eeb
		return;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	icon = _gcr_gnupg_records_get_icon (self->pv->records);
Packit b00eeb
	_gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
Packit b00eeb
	g_object_unref (icon);
Packit b00eeb
Packit b00eeb
	display = calculate_label (self);
Packit b00eeb
	_gcr_display_view_append_title (view, renderer, display);
Packit b00eeb
	g_free (display);
Packit b00eeb
Packit b00eeb
	userid = _gcr_gnupg_records_get_user_id (self->pv->records);
Packit b00eeb
	if (userid != NULL) {
Packit b00eeb
		if (_gcr_gnupg_records_parse_user_id (userid, NULL, &email, &comment)) {
Packit b00eeb
			if (email != NULL)
Packit b00eeb
				_gcr_display_view_append_content (view, renderer, _("Email"), email);
Packit b00eeb
			g_free (email);
Packit b00eeb
			if (comment != NULL)
Packit b00eeb
				_gcr_display_view_append_content (view, renderer, _("Comment"), comment);
Packit b00eeb
			g_free (comment);
Packit b00eeb
		}
Packit b00eeb
		g_free (userid);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	code = _gcr_record_get_char (self->pv->records->pdata[0], GCR_RECORD_TRUST);
Packit b00eeb
	if (code != 'e') {
Packit b00eeb
		date = _gcr_record_get_date (self->pv->records->pdata[0], GCR_RECORD_KEY_EXPIRY);
Packit b00eeb
		if (date != NULL) {
Packit b00eeb
			display = g_date_time_format (date, "%x");
Packit b00eeb
			_gcr_display_view_append_content (view, renderer, _("Expires"), display);
Packit b00eeb
			g_date_time_unref (date);
Packit b00eeb
			g_free (display);
Packit b00eeb
		}
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* The warning or status */
Packit b00eeb
	value = message_for_code (code, &message_type);
Packit b00eeb
	if (value != NULL)
Packit b00eeb
		_gcr_display_view_append_message (view, renderer, message_type, value);
Packit b00eeb
Packit b00eeb
	_gcr_display_view_start_details (view, renderer);
Packit b00eeb
Packit b00eeb
	value = _gcr_gnupg_records_get_keyid (self->pv->records);
Packit b00eeb
	last_schema = 0;
Packit b00eeb
Packit b00eeb
	for (i = 0; i < self->pv->records->len; i++) {
Packit b00eeb
		schema = _gcr_record_get_schema (self->pv->records->pdata[i]);
Packit b00eeb
		if (schema == GCR_RECORD_SCHEMA_PUB)
Packit b00eeb
			append_key_record (self, view, self->pv->records->pdata[i], _("Public Key"));
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_SUB)
Packit b00eeb
			append_key_record (self, view, self->pv->records->pdata[i], _("Public Subkey"));
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_SEC)
Packit b00eeb
			append_key_record (self, view, self->pv->records->pdata[i], _("Secret Key"));
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_SSB)
Packit b00eeb
			append_key_record (self, view, self->pv->records->pdata[i], _("Secret Subkey"));
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_UID)
Packit b00eeb
			append_uid_record (self, view, self->pv->records->pdata[i]);
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_UAT)
Packit b00eeb
			append_uat_record (self, view, self->pv->records->pdata[i]);
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_SIG)
Packit b00eeb
			append_sig_record (self, view, self->pv->records->pdata[i], value);
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_RVK)
Packit b00eeb
			append_rvk_record (self, view, self->pv->records->pdata[i]);
Packit b00eeb
		else if (schema == GCR_RECORD_SCHEMA_FPR)
Packit b00eeb
			append_fpr_record (self, view, self->pv->records->pdata[i], last_schema);
Packit b00eeb
		last_schema = schema;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	_gcr_display_view_end (view, renderer);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_gnupg_renderer_iface_init (GcrRendererIface *iface)
Packit b00eeb
{
Packit b00eeb
	iface->render_view = _gcr_gnupg_renderer_render;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
GcrGnupgRenderer *
Packit b00eeb
_gcr_gnupg_renderer_new (GPtrArray *records)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (records != NULL, NULL);
Packit b00eeb
Packit b00eeb
	return g_object_new (GCR_TYPE_GNUPG_RENDERER,
Packit b00eeb
	                     "records", records,
Packit b00eeb
	                     NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
GcrGnupgRenderer *
Packit b00eeb
_gcr_gnupg_renderer_new_for_attributes (const gchar *label,
Packit b00eeb
                                        GckAttributes *attrs)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (attrs != NULL, NULL);
Packit b00eeb
Packit b00eeb
	return g_object_new (GCR_TYPE_GNUPG_RENDERER,
Packit b00eeb
	                     "label", label,
Packit b00eeb
	                     "attributes", attrs,
Packit b00eeb
	                     NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
GPtrArray *
Packit b00eeb
_gcr_gnupg_renderer_get_records (GcrGnupgRenderer *self)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (GCR_IS_GNUPG_RENDERER (self), NULL);
Packit b00eeb
	return self->pv->records;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_gnupg_renderer_set_records (GcrGnupgRenderer *self,
Packit b00eeb
                                 GPtrArray *records)
Packit b00eeb
{
Packit b00eeb
	g_return_if_fail (GCR_IS_GNUPG_RENDERER (self));
Packit b00eeb
Packit b00eeb
	if (records)
Packit b00eeb
		g_ptr_array_ref (records);
Packit b00eeb
	if (self->pv->records)
Packit b00eeb
		g_ptr_array_unref (self->pv->records);
Packit b00eeb
	self->pv->records = records;
Packit b00eeb
Packit b00eeb
	if (self->pv->attrs) {
Packit b00eeb
		gck_attributes_unref (self->pv->attrs);
Packit b00eeb
		self->pv->attrs = NULL;
Packit b00eeb
		g_object_notify (G_OBJECT (self), "attributes");
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
	g_object_notify (G_OBJECT (self), "records");
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
GckAttributes*
Packit b00eeb
_gcr_gnupg_renderer_get_attributes (GcrGnupgRenderer *self)
Packit b00eeb
{
Packit b00eeb
	g_return_val_if_fail (GCR_IS_GNUPG_RENDERER (self), NULL);
Packit b00eeb
	return self->pv->attrs;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_gnupg_renderer_set_attributes (GcrGnupgRenderer *self,
Packit b00eeb
                                    GckAttributes *attrs)
Packit b00eeb
{
Packit b00eeb
	const GckAttribute *attr;
Packit b00eeb
	GPtrArray *records;
Packit b00eeb
Packit b00eeb
	g_return_if_fail (GCR_IS_GNUPG_RENDERER (self));
Packit b00eeb
Packit b00eeb
	attr = gck_attributes_find (attrs, CKA_VALUE);
Packit b00eeb
	g_return_if_fail (attr != NULL);
Packit b00eeb
	records = _gcr_records_parse_colons (attr->value, attr->length);
Packit b00eeb
	g_return_if_fail (records != NULL);
Packit b00eeb
Packit b00eeb
	if (attrs)
Packit b00eeb
		gck_attributes_ref (attrs);
Packit b00eeb
	gck_attributes_unref (self->pv->attrs);
Packit b00eeb
	self->pv->attrs = attrs;
Packit b00eeb
Packit b00eeb
	if (self->pv->records)
Packit b00eeb
		g_ptr_array_unref (self->pv->records);
Packit b00eeb
	self->pv->records = records;
Packit b00eeb
	g_object_notify (G_OBJECT (self), "records");
Packit b00eeb
Packit b00eeb
	gcr_renderer_emit_data_changed (GCR_RENDERER (self));
Packit b00eeb
	g_object_notify (G_OBJECT (self), "attributes");
Packit b00eeb
Packit b00eeb
}