예제 #1
0
static DBusMessage*
service_method_create_collection (GkdSecretService *self, DBusMessage *message)
{
	DBusMessageIter iter, array;
	GckAttributes *attrs;
	GkdSecretCreate *create;
	DBusMessage *reply;
	const gchar *path;
	const gchar *alias;
	const char *caller;
	const gchar *coll;

	/* Parse the incoming message */
	if (!dbus_message_has_signature (message, "a{sv}s"))
		return NULL;
	if (!dbus_message_iter_init (message, &iter))
		g_return_val_if_reached (NULL);
	attrs = gck_attributes_new ();
	dbus_message_iter_recurse (&iter, &array);
	if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, attrs)) {
		gck_attributes_unref (attrs);
		return dbus_message_new_error_printf (message, DBUS_ERROR_INVALID_ARGS,
		                                      "Invalid properties");
	}
	if (!dbus_message_iter_next (&iter))
		g_return_val_if_reached (NULL);
	dbus_message_iter_get_basic (&iter, &alias);

	/* Empty alias is no alias */
	if (alias) {
		if (!alias[0]) {
			alias = NULL;
		} else if (!g_str_equal (alias, "default")) {
			gck_attributes_unref (attrs);
			return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED,
			                               "Only the 'default' alias is supported");
		}
	}

	gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);

	/* Create the prompt object, for the password */
	caller = dbus_message_get_sender (message);
	create = gkd_secret_create_new (self, caller, attrs, alias);
	gck_attributes_unref (attrs);

	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create));
	gkd_secret_service_publish_dispatch (self, caller,
	                                     GKD_SECRET_DISPATCH (create));

	coll = "/";
	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply,
	                          DBUS_TYPE_OBJECT_PATH, &coll,
	                          DBUS_TYPE_OBJECT_PATH, &path,
	                          DBUS_TYPE_INVALID);

	g_object_unref (create);
	return reply;
}
예제 #2
0
gchar*
gkd_secret_create_with_secret (GckAttributes *attrs, GkdSecretSecret *master,
                               DBusError *derr)
{
	GckAttributes *atts;
	GckObject *cred;
	GckObject *collection;
	GckSession *session;
	GError *error = NULL;
	gpointer identifier;
	gsize n_identifier;
	gboolean token;
	gchar *path;

	if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
		token = FALSE;

	atts = gck_attributes_new ();
	gck_attributes_add_ulong (atts, CKA_CLASS, CKO_G_CREDENTIAL);
	gck_attributes_add_boolean (atts, CKA_MATE_TRANSIENT, TRUE);
	gck_attributes_add_boolean (atts, CKA_TOKEN, token);

	session = gkd_secret_session_get_pkcs11_session (master->session);
	g_return_val_if_fail (session, NULL);

	/* Create ourselves some credentials */
	cred = gkd_secret_session_create_credential (master->session, session, atts, master, derr);
	gck_attributes_unref (atts);

	if (cred == NULL)
		return FALSE;

	collection = gkd_secret_create_with_credential (session, attrs, cred, &error);

	gck_attributes_unref (atts);
	g_object_unref (cred);

	if (collection == NULL) {
		g_warning ("couldn't create collection: %s", egg_error_message (error));
		g_clear_error (&error);
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't create new collection");
		return FALSE;
	}

	identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, &error);
	g_object_unref (collection);

	if (!identifier) {
		g_warning ("couldn't lookup new collection identifier: %s", egg_error_message (error));
		g_clear_error (&error);
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't find new collection just created");
		return FALSE;
	}

	path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
	g_free (identifier);
	return path;
}
예제 #3
0
static GckObject *
lookup_public_key (GckObject *object,
                   GCancellable *cancellable,
                   GError **lerror)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	gulong attr_types[] = { CKA_ID };
	GckAttributes *attrs;
	GError *error = NULL;
	GckSession *session;
	GckObject *result;
	const GckAttribute *id;
	GList *objects;

	attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
	                                 cancellable, &error);
	if (error != NULL) {
		_gcr_debug ("couldn't load private key id: %s", error->message);
		g_propagate_error (lerror, error);
		return NULL;
	}

	id = gck_attributes_find (attrs, CKA_ID);
	if (id == NULL || gck_attribute_is_invalid (id)) {
		gck_attributes_unref (attrs);
		_gcr_debug ("couldn't load private key id");
		g_set_error_literal (lerror, GCK_ERROR, CKR_ATTRIBUTE_TYPE_INVALID,
		                     gck_message_from_rv (CKR_ATTRIBUTE_TYPE_INVALID));
		return NULL;
	}

	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
	gck_builder_add_attribute (&builder, id);
	gck_attributes_unref (attrs);

	session = gck_object_get_session (object);
	objects = gck_session_find_objects (session, gck_builder_end (&builder), cancellable, &error);
	g_object_unref (session);

	if (error != NULL) {
		_gcr_debug ("couldn't lookup public key: %s", error->message);
		g_propagate_error (lerror, error);
		return NULL;
	}

	if (!objects)
		return NULL;

	result = g_object_ref (objects->data);
	gck_list_unref_free (objects);

	return result;
}
예제 #4
0
static GckObject*
create_credential (GckSession *session, GckObject *object,
                   const gchar *secret, GError **error)
{
	GckAttributes *attrs;
	GckObject *cred;

	g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
	g_return_val_if_fail (!object || GCK_IS_OBJECT (object), NULL);

	if (!secret)
		secret = "";

	attrs = gck_attributes_new ();
	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_G_CREDENTIAL);
	gck_attributes_add_string (attrs, CKA_VALUE, secret);
	gck_attributes_add_boolean (attrs, CKA_MATE_TRANSIENT, TRUE);
	gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);

	if (object)
		gck_attributes_add_ulong (attrs, CKA_G_OBJECT,
		                          gck_object_get_handle (object));

	cred = gck_session_create_object (session, attrs, NULL, error);
	gck_attributes_unref (attrs);

	return cred;
}
예제 #5
0
GckObject*
gkd_secret_create_with_credential (GckSession *session, GckAttributes *attrs,
                                   GckObject *cred, GError **error)
{
	GckAttributes *atts;
	GckAttribute *attr;
	GckObject *collection;
	gboolean token;

	atts = gck_attributes_new ();
	gck_attributes_add_ulong (atts, CKA_G_CREDENTIAL, gck_object_get_handle (cred));
	gck_attributes_add_ulong (atts, CKA_CLASS, CKO_G_COLLECTION);

	attr = gck_attributes_find (attrs, CKA_LABEL);
	if (attr != NULL)
		gck_attributes_add (atts, attr);
	if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
		token = FALSE;
	gck_attributes_add_boolean (atts, CKA_TOKEN, token);

	collection = gck_session_create_object (session, atts, NULL, error);
	gck_attributes_unref (atts);

	return collection;
}
예제 #6
0
GNode *
_gcr_subject_public_key_load (GckObject *key,
                              GCancellable *cancellable,
                              GError **error)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckAttributes *attributes;
	GNode *asn;

	g_return_val_if_fail (GCK_IS_OBJECT (key), NULL);
	g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
	g_return_val_if_fail (error == NULL || *error == NULL, NULL);

	lookup_attributes (key, &builder);

	if (!check_attributes (&builder)) {
		if (!load_attributes (key, &builder, cancellable, error)) {
			gck_builder_clear (&builder);
			return NULL;
		}
	}

	attributes = gck_builder_end (&builder);
	asn = _gcr_subject_public_key_for_attributes (attributes);
	if (asn == NULL) {
		g_set_error_literal (error, GCK_ERROR, CKR_TEMPLATE_INCONSISTENT,
		                     _("Couldn't build public key"));
	}

	gck_attributes_unref (attributes);
	return asn;
}
예제 #7
0
GNode *
_gcr_subject_public_key_load_finish (GAsyncResult *result,
                                     GError **error)
{
	GckAttributes *attributes;
	GSimpleAsyncResult *res;
	LoadClosure *closure;
	GNode *asn;

	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
	g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL,
	                      _gcr_subject_public_key_load_async), NULL);

	res = G_SIMPLE_ASYNC_RESULT (result);
	if (g_simple_async_result_propagate_error (res, error))
		return NULL;

	closure = g_simple_async_result_get_op_res_gpointer (res);
	attributes = gck_attributes_ref_sink (gck_builder_end (&closure->builder));
	asn = _gcr_subject_public_key_for_attributes (attributes);
	if (asn == NULL) {
		g_set_error_literal (error, GCK_ERROR, CKR_TEMPLATE_INCONSISTENT,
		                     _("Couldn't build public key"));
	}

	gck_attributes_unref (attributes);
	return asn;
}
예제 #8
0
static void
complete_generate (SeahorsePkcs11Generate *self,
                   GError **error)
{
	g_assert (error != NULL);

	if (*error != NULL)
		seahorse_util_handle_error (error, NULL, _("Couldn't generate private key"));
	else
		seahorse_place_load (SEAHORSE_PLACE (self->token), self->cancellable, NULL, NULL);

	g_clear_object (&self->cancellable);
	gck_attributes_unref (self->pub_attrs);
	gck_attributes_unref (self->prv_attrs);
	self->pub_attrs = self->prv_attrs = NULL;
}
예제 #9
0
static GckObject*
lookup_login_keyring (GckSession *session)
{
	GckAttributes *atts;
	GError *error = NULL;
	GckObject *login = NULL;
	GList *objects;
	guint length;

	g_return_val_if_fail (GCK_IS_SESSION (session), NULL);

	atts = gck_attributes_new ();
	gck_attributes_add_ulong (atts, CKA_CLASS, CKO_G_COLLECTION);
	gck_attributes_add_boolean (atts, CKA_TOKEN, TRUE);
	gck_attributes_add_string (atts, CKA_ID, "login");

	objects = gck_session_find_objects (session, atts, NULL, &error);
	gck_attributes_unref (atts);

	if (error) {
		g_warning ("couldn't search for login keyring: %s", egg_error_message (error));
		g_clear_error (&error);
		return NULL;
	}

	length = g_list_length (objects);
	if (length == 1)
		login = g_object_ref (objects->data);
	else if (length > 1)
		g_warning ("more than one login keyring exists");

	gck_list_unref_free (objects);
	return login;
}
예제 #10
0
static void
imported_object (GckObject *object,
                 const gchar *destination)
{
	gulong attr_types[3];
	GckAttributes *attrs;
	const GckAttribute *id;
	CK_OBJECT_CLASS klass;
	const gchar *message;
	GError *err = NULL;
	gchar *label, *hex;

	attr_types[0] = CKA_LABEL;
	attr_types[1] = CKA_CLASS;
	attr_types[2] = CKA_ID;

	attrs = gck_object_get_full (object, attr_types, G_N_ELEMENTS (attr_types), NULL, &err);
	if (attrs == NULL) {
		gkr_tool_handle_error (&err, "couldn't get imported object info");
		return;
	}

	if (!gck_attributes_find_string (attrs, CKA_LABEL, &label))
		label = g_strdup ("unknown");
	if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
		klass = CKO_DATA;
	id = gck_attributes_find (attrs, CKA_ID);
	
	switch (klass) {
	case CKO_CERTIFICATE:
		message = "%s: imported certificate: %s\n";
		break;
	case CKO_DATA:
		message = "%s: imported data: %s\n";
		break;
	case CKO_PRIVATE_KEY:
		message = "%s: imported private key: %s\n";
		break;
	case CKO_PUBLIC_KEY:
		message = "%s: imported public key: %s\n";
		break;
	case CKO_SECRET_KEY:
		message = "%s: imported secret key: %s\n";
		break;
	default:
		message = "%s: imported object: %s\n";
		break;
	};
	
	g_print (message, destination, label);

	if (id) {
		hex = egg_hex_encode (id->value, id->length);
		g_print ("\tidentifier: %s\n", hex);
		g_free (hex);
	}

	gck_attributes_unref (attrs);
	g_free (label);
}
예제 #11
0
static gboolean
load_rsa_attributes (GckObject *object,
                     GckBuilder *builder,
                     GCancellable *cancellable,
                     GError **lerror)
{
	gulong attr_types[] = { CKA_MODULUS, CKA_PUBLIC_EXPONENT };
	GckAttributes *attrs;
	GError *error = NULL;

	if (check_rsa_attributes (builder)) {
		_gcr_debug ("rsa attributes already loaded");
		return TRUE;
	}

	attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
	                                 cancellable, &error);
	if (error != NULL) {
		_gcr_debug ("couldn't load rsa attributes: %s", error->message);
		g_propagate_error (lerror, error);
		return FALSE;
	}

	gck_builder_set_all (builder, attrs);
	gck_attributes_unref (attrs);

	return check_rsa_attributes (builder);
}
예제 #12
0
static void
seahorse_pkcs11_generate_finalize (GObject *obj)
{
	SeahorsePkcs11Generate *self = SEAHORSE_PKCS11_GENERATE (obj);

	g_clear_object (&self->token);
	g_clear_object (&self->token_model);

	g_free (self->mechanism);
	g_clear_object (&self->mechanism_store);

	g_clear_object (&self->cancellable);
	gck_attributes_unref (self->pub_attrs);
	gck_attributes_unref (self->prv_attrs);

	G_OBJECT_CLASS (seahorse_pkcs11_generate_parent_class)->finalize (obj);
}
예제 #13
0
static DBusMessage*
service_method_create_with_master_password (GkdSecretService *self, DBusMessage *message)
{
	DBusError derr = DBUS_ERROR_INIT;
	DBusMessageIter iter, array;
	DBusMessage *reply = NULL;
	GkdSecretSecret *secret = NULL;
	GckAttributes *attrs = NULL;
	gchar *path;

	/* Parse the incoming message */
	if (!dbus_message_has_signature (message, "a{sv}(oayays)"))
		return NULL;
	if (!dbus_message_iter_init (message, &iter))
		g_return_val_if_reached (NULL);
	attrs = gck_attributes_new ();
	dbus_message_iter_recurse (&iter, &array);
	if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, attrs)) {
		gck_attributes_unref (attrs);
		return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
		                               "Invalid properties argument");
	}
	dbus_message_iter_next (&iter);
	secret = gkd_secret_secret_parse (self, message, &iter, &derr);
	if (secret == NULL) {
		gck_attributes_unref (attrs);
		return gkd_secret_error_to_reply (message, &derr);
	}

	gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
	path = gkd_secret_create_with_secret (attrs, secret, &derr);
	gck_attributes_unref (attrs);
	gkd_secret_secret_free (secret);

	if (path == NULL)
		return gkd_secret_error_to_reply (message, &derr);

	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
	g_free (path);

	return reply;
}
예제 #14
0
static void
gkd_secret_create_finalize (GObject *obj)
{
	GkdSecretCreate *self = GKD_SECRET_CREATE (obj);

	gck_attributes_unref (self->pkcs11_attrs);
	g_free (self->result_path);
	g_free (self->alias);

	G_OBJECT_CLASS (gkd_secret_create_parent_class)->finalize (obj);
}
예제 #15
0
static gboolean
service_method_create_with_master_password (GkdExportedInternal *skeleton,
					    GDBusMethodInvocation *invocation,
					    GVariant *attributes,
					    GVariant *master,
					    GkdSecretService *self)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GkdSecretSecret *secret = NULL;
	GckAttributes *attrs = NULL;
	GError *error = NULL;
	gchar *path;
	const gchar *caller;

	if (!gkd_secret_property_parse_all (attributes, SECRET_COLLECTION_INTERFACE, &builder)) {
		gck_builder_clear (&builder);
		g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_INVALID_ARGS,
							       "Invalid properties argument");
		return TRUE;
	}

	caller = g_dbus_method_invocation_get_sender (invocation);
	secret = gkd_secret_secret_parse (self,
					  caller,
					  master, &error);
	if (secret == NULL) {
		gck_builder_clear (&builder);
		g_dbus_method_invocation_take_error (invocation, error);
		return TRUE;
	}

	gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
	path = gkd_secret_create_with_secret (attrs, secret, &error);
	gck_attributes_unref (attrs);
	gkd_secret_secret_free (secret);

	if (path == NULL) {
		gkd_secret_propagate_error (invocation, "Couldn't create collection", error);
		return TRUE;
	}

	/* Notify the callers that a collection was created */
        g_message ("emit collection_Created");
	gkd_secret_service_emit_collection_created (self, path);

	gkd_exported_internal_complete_create_with_master_password
		(skeleton, invocation, path);
	g_free (path);

	return TRUE;
}
예제 #16
0
static void
gcr_key_renderer_set_property (GObject *obj, guint prop_id, const GValue *value,
                               GParamSpec *pspec)
{
	GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);

	switch (prop_id) {
	case PROP_LABEL:
		g_free (self->pv->label);
		self->pv->label = g_value_dup_string (value);
		g_object_notify (obj, "label");
		gcr_renderer_emit_data_changed (GCR_RENDERER (self));
		break;
	case PROP_ATTRIBUTES:
		gck_attributes_unref (self->pv->attributes);
		self->pv->attributes = g_value_dup_boxed (value);
		gcr_renderer_emit_data_changed (GCR_RENDERER (self));
		break;
	case PROP_OBJECT:
		g_clear_object (&self->pv->object);
		self->pv->object = g_value_dup_object (value);
		if (self->pv->object) {
			gck_attributes_unref (self->pv->attributes);
			self->pv->attributes = NULL;
		}
		if (GCK_IS_OBJECT_CACHE (self->pv->object)) {
			self->pv->notify_sig = g_signal_connect (self->pv->object,
			                                         "notify::attributes",
			                                         G_CALLBACK (on_object_cache_attributes),
			                                         self);
			on_object_cache_attributes (G_OBJECT (self->pv->object), NULL, self);
		}
		g_object_notify (obj, "attributes");
		g_object_notify (obj, "object");
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
		break;
	}
}
예제 #17
0
gchar*
gkd_secret_create_with_secret (GckAttributes *attrs,
                               GkdSecretSecret *master,
                               GError **error)
{
    GckBuilder builder = GCK_BUILDER_INIT;
    GckAttributes *atts;
    GckObject *cred;
    GckObject *collection;
    GckSession *session;
    gpointer identifier;
    gsize n_identifier;
    gboolean token;
    gchar *path;

    if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
        token = FALSE;

    gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_CREDENTIAL);
    gck_builder_add_boolean (&builder, CKA_GNOME_TRANSIENT, TRUE);
    gck_builder_add_boolean (&builder, CKA_TOKEN, token);

    session = gkd_secret_session_get_pkcs11_session (master->session);
    g_return_val_if_fail (session, NULL);

    /* Create ourselves some credentials */
    atts = gck_attributes_ref_sink (gck_builder_end (&builder));
    cred = gkd_secret_session_create_credential (master->session, session,
            atts, master, error);
    gck_attributes_unref (atts);

    if (cred == NULL)
        return FALSE;

    collection = gkd_secret_create_with_credential (session, attrs, cred, error);

    g_object_unref (cred);

    if (collection == NULL)
        return FALSE;

    identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, error);
    g_object_unref (collection);

    if (!identifier)
        return FALSE;

    path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
    g_free (identifier);
    return path;
}
예제 #18
0
static gboolean
service_method_create_collection (GkdExportedService *skeleton,
				  GDBusMethodInvocation *invocation,
				  GVariant *properties,
				  gchar *alias,
				  GkdSecretService *self)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckAttributes *attrs;
	GkdSecretCreate *create;
	const gchar *path;
	const char *caller;

	if (!gkd_secret_property_parse_all (properties, SECRET_COLLECTION_INTERFACE, &builder)) {
		gck_builder_clear (&builder);
		g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_INVALID_ARGS,
							       "Invalid properties");
		return TRUE;
	}

	/* Empty alias is no alias */
	if (alias) {
		if (!alias[0]) {
			alias = NULL;
		} else if (!g_str_equal (alias, "default")) {
			gck_builder_clear (&builder);
			g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
								       G_DBUS_ERROR_NOT_SUPPORTED,
								       "Only the 'default' alias is supported");
			return TRUE;
		}
	}

	gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));

	/* Create the prompt object, for the password */
	caller = g_dbus_method_invocation_get_sender (invocation);
	create = gkd_secret_create_new (self, caller, attrs, alias);
	gck_attributes_unref (attrs);

	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create));
	gkd_secret_service_publish_dispatch (self, caller,
					     GKD_SECRET_DISPATCH (create));

	gkd_exported_service_complete_create_collection (skeleton, invocation,
							 "/", path);
	return TRUE;
}
예제 #19
0
/**
 * gcr_key_renderer_set_attributes:
 * @self: The key renderer
 * @attrs: (allow-none): the attributes to display
 *
 * Get the attributes displayed in the renderer. The attributes should represent
 * either an RSA, DSA, or EC key in PKCS\#11 style.
 */
void
gcr_key_renderer_set_attributes (GcrKeyRenderer *self, GckAttributes *attrs)
{
	g_return_if_fail (GCR_IS_KEY_RENDERER (self));

	if (self->pv->attributes)
		gck_attributes_unref (self->pv->attributes);
	self->pv->attributes = attrs;
	if (self->pv->attributes)
		gck_attributes_ref (self->pv->attributes);

	g_object_notify (G_OBJECT (self), "attributes");
	gcr_renderer_emit_data_changed (GCR_RENDERER (self));
}
예제 #20
0
static DBusMessage*
service_method_create_with_master_password (GkdSecretService *self, DBusMessage *message)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	DBusError derr = DBUS_ERROR_INIT;
	DBusMessageIter iter, array;
	DBusMessage *reply = NULL;
	GkdSecretSecret *secret = NULL;
	GckAttributes *attrs = NULL;
	GError *error = NULL;
	gchar *path;

	/* Parse the incoming message */
	if (!dbus_message_has_signature (message, "a{sv}(oayays)"))
		return NULL;
	if (!dbus_message_iter_init (message, &iter))
		g_return_val_if_reached (NULL);
	dbus_message_iter_recurse (&iter, &array);
	if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, &builder)) {
		gck_builder_clear (&builder);
		return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
		                               "Invalid properties argument");
	}
	dbus_message_iter_next (&iter);
	secret = gkd_secret_secret_parse (self, message, &iter, &derr);
	if (secret == NULL) {
		gck_builder_clear (&builder);
		return gkd_secret_error_to_reply (message, &derr);
	}

	gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
	path = gkd_secret_create_with_secret (attrs, secret, &error);
	gck_attributes_unref (attrs);
	gkd_secret_secret_free (secret);

	if (path == NULL)
		return gkd_secret_propagate_error (message, "Couldn't create collection", error);

	/* Notify the callers that a collection was created */
	gkd_secret_service_emit_collection_created (self, path);

	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
	g_free (path);

	return reply;
}
예제 #21
0
static void
lookup_attributes (GckObject *object,
                   GckBuilder *builder)
{
	GckObjectCache *oakey;
	GckAttributes *attrs;

	if (GCK_IS_OBJECT_CACHE (object)) {
		oakey = GCK_OBJECT_CACHE (object);
		attrs = gck_object_cache_get_attributes (oakey);
		if (attrs != NULL) {
			gck_builder_add_all (builder, attrs);
			gck_attributes_unref (attrs);
		}
	}
}
예제 #22
0
static gboolean
load_dsa_attributes (GckObject *object,
                     GckBuilder *builder,
                     GCancellable *cancellable,
                     GError **lerror)
{
	gulong attr_types[] = { CKA_PRIME, CKA_SUBPRIME, CKA_BASE, CKA_VALUE };
	GError *error = NULL;
	GckAttributes *loaded;
	GckObject *publi;
	gulong klass;

	if (check_dsa_attributes (builder))
		return TRUE;

	if (!gck_builder_find_ulong (builder, CKA_CLASS, &klass))
		g_return_val_if_reached (FALSE);

	/* If it's a private key, find the public one */
	if (klass == CKO_PRIVATE_KEY)
		publi = lookup_public_key (object, cancellable, lerror);

	else
		publi = g_object_ref (object);

	if (!publi)
		return FALSE;

	loaded = gck_object_cache_lookup (publi, attr_types, G_N_ELEMENTS (attr_types),
	                                  cancellable, &error);
	g_object_unref (publi);

	if (error != NULL) {
		_gcr_debug ("couldn't load rsa attributes: %s", error->message);
		g_propagate_error (lerror, error);
		return FALSE;
	}

	/* We've made sure to load info from the public key, so change class */
	gck_builder_set_ulong (builder, CKA_CLASS, CKO_PUBLIC_KEY);

	gck_builder_set_all (builder, loaded);
	gck_attributes_unref (loaded);

	return check_dsa_attributes (builder);
}
예제 #23
0
static void
gcr_key_renderer_finalize (GObject *obj)
{
	GcrKeyRenderer *self = GCR_KEY_RENDERER (obj);

	if (self->pv->attributes)
		gck_attributes_unref (self->pv->attributes);
	self->pv->attributes = NULL;

	g_free (self->pv->label);
	self->pv->label = NULL;

	if (self->pv->icon)
		g_object_unref (self->pv->icon);
	self->pv->icon = NULL;

	G_OBJECT_CLASS (gcr_key_renderer_parent_class)->finalize (obj);
}
예제 #24
0
static GckObject*
create_login_keyring (GckSession *session, GckObject *cred, GError **error)
{
	GckObject *login;
	GckAttributes *atts;

	g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
	g_return_val_if_fail (GCK_IS_OBJECT (cred), NULL);

	atts = gck_attributes_new ();
	gck_attributes_add_ulong (atts, CKA_CLASS, CKO_G_COLLECTION);
	gck_attributes_add_string (atts, CKA_ID, "login");
	gck_attributes_add_ulong (atts, CKA_G_CREDENTIAL, gck_object_get_handle (cred));
	gck_attributes_add_boolean (atts, CKA_TOKEN, TRUE);

	/* TRANSLATORS: This is the display label for the login keyring */
	gck_attributes_add_string (atts, CKA_LABEL, _("Login"));

	login = gck_session_create_object (session, atts, NULL, error);
	gck_attributes_unref (atts);

	return login;
}
예제 #25
0
static gboolean
load_object_basics (GckObject *object,
                    GckBuilder *builder,
                    GCancellable *cancellable,
                    gulong *klass,
                    gulong *type,
                    GError **lerror)
{
	gulong attr_types[] = { CKA_CLASS, CKA_KEY_TYPE, CKA_CERTIFICATE_TYPE };
	GckAttributes *attrs;
	GError *error = NULL;

	g_assert (klass != NULL);
	g_assert (type != NULL);

	if (check_object_basics (builder, klass, type)) {
		_gcr_debug ("already loaded: class = %lu, type = %lu", *klass, *type);
		return TRUE;
	}

	attrs = gck_object_cache_lookup (object, attr_types, G_N_ELEMENTS (attr_types),
	                                 cancellable, &error);
	if (error != NULL) {
		_gcr_debug ("couldn't load: %s", error->message);
		g_propagate_error (lerror, error);
		return FALSE;
	}

	gck_builder_set_all (builder, attrs);
	gck_attributes_unref (attrs);

	if (!check_object_basics (builder, klass, type))
		return FALSE;

	_gcr_debug ("loaded: class = %lu, type = %lu", *klass, *type);
	return TRUE;
}
예제 #26
0
static void
gcr_key_widget_class_init (GcrKeyWidgetClass *klass)
{
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
	GckAttributes *registered;

	gcr_key_widget_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (GcrKeyWidgetPrivate));

	gobject_class->constructor = gcr_key_widget_constructor;
	gobject_class->finalize = gcr_key_widget_finalize;
	gobject_class->set_property = gcr_key_widget_set_property;
	gobject_class->get_property = gcr_key_widget_get_property;

	g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
	         g_param_spec_boxed ("attributes", "Attributes", "The data displayed in the widget",
	                             GCK_TYPE_ATTRIBUTES, G_PARAM_READWRITE));

	/* Register this as a view which can be loaded */
	registered = gck_attributes_new ();
	gck_attributes_add_ulong (registered, CKA_CLASS, CKO_PRIVATE_KEY);
	gcr_renderer_register (GCR_TYPE_KEY_WIDGET, registered);
	gck_attributes_unref (registered);
}
예제 #27
0
static gboolean
change_or_create_login (GList *modules, const gchar *original, const gchar *master)
{
	GError *error = NULL;
	GckSession *session;
	GckObject *login = NULL;
	GckObject *ocred = NULL;
	GckObject *mcred = NULL;
	gboolean success = FALSE;
	GckAttributes *atts;

	g_return_val_if_fail (original, FALSE);
	g_return_val_if_fail (master, FALSE);

	/* Find the login object */
	session = lookup_login_session (modules);
	login = lookup_login_keyring (session);

	/* Create the new credential we'll be changing to */
	mcred = create_credential (session, NULL, master, &error);
	if (mcred == NULL) {
		g_warning ("couldn't create new login credential: %s", egg_error_message (error));
		g_clear_error (&error);

	/* Create original credentials */
	} else if (login) {
		ocred = create_credential (session, login, original, &error);
		if (ocred == NULL) {
			if (g_error_matches (error, GCK_ERROR, CKR_PIN_INCORRECT)) {
				g_message ("couldn't change login master password, "
				           "original password was wrong: %s",
				           egg_error_message (error));
			} else {
				g_warning ("couldn't create original login credential: %s",
				           egg_error_message (error));
			}
			g_clear_error (&error);
		}
	}

	/* No keyring? try to create */
	if (!login && mcred) {
		login = create_login_keyring (session, mcred, &error);
		if (login == NULL) {
			g_warning ("couldn't create login keyring: %s", egg_error_message (error));
			g_clear_error (&error);
		} else {
			success = TRUE;
		}

	/* Change the master password */
	} else if (login && ocred && mcred) {
		atts = gck_attributes_new ();
		gck_attributes_add_ulong (atts, CKA_G_CREDENTIAL, gck_object_get_handle (mcred));
		if (!gck_object_set (login, atts, NULL, &error)) {
			g_warning ("couldn't change login master password: %s", egg_error_message (error));
			g_clear_error (&error);
		} else {
			success = TRUE;
		}
		gck_attributes_unref (atts);
	}

	if (ocred) {
		gck_object_destroy (ocred, NULL, NULL);
		g_object_unref (ocred);
	}
	if (mcred)
		g_object_unref (mcred);
	if (login)
		g_object_unref (login);
	if (session)
		g_object_unref (session);

	return success;
}
예제 #28
0
파일: gcr-importer.c 프로젝트: UIKit0/gcr
/**
 * gcr_importer_create_for_parsed:
 * @parsed: a parser with a parsed item to import
 *
 * Create a set of importers which can import this parsed item.
 * The parsed item is represented by the state of the GcrParser at the
 * time of calling this method.
 *
 * Returns: (element-type Gcr.Importer) (transfer full): a list of importers
 *          which can import the parsed item, which should be freed with
 *          g_object_unref(), or %NULL if no types of importers can be created
 */
GList *
gcr_importer_create_for_parsed (GcrParsed *parsed)
{
	GcrRegistered *registered;
	GcrImporterIface *iface;
	gpointer instance_class;
	GckAttributes *attrs;
	gboolean matched;
	gulong n_attrs;
	GList *results = NULL;
	GHashTable *seen;
	gulong j;
	gsize i;

	g_return_val_if_fail (parsed != NULL, NULL);

	gcr_importer_register_well_known ();

	if (!registered_importers)
		return NULL;

	if (!registered_sorted) {
		g_array_sort (registered_importers, sort_registered_by_n_attrs);
		registered_sorted = TRUE;
	}

	attrs = gcr_parsed_get_attributes (parsed);
	if (attrs != NULL)
		gck_attributes_ref (attrs);
	else
		attrs = gck_attributes_new_empty (GCK_INVALID);

	seen = g_hash_table_new (g_direct_hash, g_direct_equal);

	if (_gcr_debugging) {
		gchar *a = gck_attributes_to_string (attrs);
		_gcr_debug ("looking for importer for: %s", a);
		g_free (a);
	}

	for (i = 0; i < registered_importers->len; ++i) {
		registered = &(g_array_index (registered_importers, GcrRegistered, i));
		n_attrs = gck_attributes_count (registered->attrs);

		matched = TRUE;

		for (j = 0; j < n_attrs; ++j) {
			if (!gck_attributes_contains (attrs, gck_attributes_at (registered->attrs, j))) {
				matched = FALSE;
				break;
			}
		}

		if (_gcr_debugging) {
			gchar *a = gck_attributes_to_string (registered->attrs);
			_gcr_debug ("importer %s %s: %s", g_type_name (registered->importer_type),
			            matched ? "matched" : "didn't match", a);
			g_free (a);
		}

		if (matched) {
			if (check_if_seen_or_add (seen, GUINT_TO_POINTER (registered->importer_type)))
				continue;

			instance_class = g_type_class_ref (registered->importer_type);

			iface = g_type_interface_peek (instance_class, GCR_TYPE_IMPORTER);
			g_return_val_if_fail (iface != NULL, NULL);
			g_return_val_if_fail (iface->create_for_parsed, NULL);
			results = g_list_concat (results, (iface->create_for_parsed) (parsed));

			g_type_class_unref (instance_class);
		}
	}

	g_hash_table_unref (seen);
	gck_attributes_unref (attrs);
	return results;
}
예제 #29
0
static void
gcr_key_renderer_real_render (GcrRenderer *renderer, GcrViewer *viewer)
{
	GcrKeyRenderer *self;
	GcrDisplayView *view;
	const gchar *text = "";
	GckAttributes *attrs;
	gpointer fingerprint;
	gsize n_fingerprint;
	gchar *display;
	gulong klass;
	gulong key_type;
	guint size;

	self = GCR_KEY_RENDERER (renderer);

	if (GCR_IS_DISPLAY_VIEW (viewer)) {
		view = GCR_DISPLAY_VIEW (viewer);

	} else {
		g_warning ("GcrKeyRenderer only works with internal specific "
		           "GcrViewer returned by gcr_viewer_new().");
		return;
	}

	_gcr_display_view_begin (view, renderer);

	attrs = calculate_attrs (self);
	if (attrs == NULL) {
		_gcr_display_view_end (view, renderer);
		return;
	}

	if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) ||
	    !gck_attributes_find_ulong (attrs, CKA_KEY_TYPE, &key_type)) {
		g_warning ("private key does not have the CKA_CLASS and CKA_KEY_TYPE attributes");
		_gcr_display_view_end (view, renderer);
		gck_attributes_unref (attrs);
		return;
	}

	_gcr_display_view_set_icon (view, renderer, self->pv->icon);

	display = calculate_label (self);
	_gcr_display_view_append_title (view, renderer, display);
	g_free (display);

	if (klass == CKO_PRIVATE_KEY) {
		if (key_type == CKK_RSA)
			text = _("Private RSA Key");
		else if (key_type == CKK_DSA)
			text = _("Private DSA Key");
		else if (key_type == CKK_EC)
			text = _("Private Elliptic Curve Key");
		else
			text = _("Private Key");
	} else if (klass == CKO_PUBLIC_KEY) {
		if (key_type == CKK_RSA)
			text = _("Public DSA Key");
		else if (key_type == CKK_DSA)
			text = _("Public DSA Key");
		else if (key_type == CKK_EC)
			text = _("Public Elliptic Curve Key");
		else
			text = _("Public Key");
	}

	_gcr_display_view_append_content (view, renderer, text, NULL);

	size = _gcr_subject_public_key_attributes_size (attrs);
	if (size > 0) {
		display = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%u bit", "%u bits", size), size);
		_gcr_display_view_append_content (view, renderer, _("Strength"), display);
		g_free (display);
	}

	_gcr_display_view_start_details (view, renderer);

	if (key_type == CKK_RSA)
		text = _("RSA");
	else if (key_type == CKK_DSA)
		text = _("DSA");
	else if (key_type == CKK_EC)
		text = _("Elliptic Curve");
	else
		text = _("Unknown");
	_gcr_display_view_append_value (view, renderer, _("Algorithm"), text, FALSE);

	if (size == 0)
		display = g_strdup (_("Unknown"));
	else
		display = g_strdup_printf ("%u", size);
	_gcr_display_view_append_value (view, renderer, _("Size"), display, FALSE);
	g_free (display);

	/* Fingerprints */
	_gcr_display_view_append_heading (view, renderer, _("Fingerprints"));

	fingerprint = calculate_fingerprint (self, attrs, G_CHECKSUM_SHA1, &n_fingerprint);
	if (fingerprint) {
		_gcr_display_view_append_hex (view, renderer, _("SHA1"), fingerprint, n_fingerprint);
		g_free (fingerprint);
	}
	fingerprint = calculate_fingerprint (self, attrs, G_CHECKSUM_SHA256, &n_fingerprint);
	if (fingerprint) {
		_gcr_display_view_append_hex (view, renderer, _("SHA256"), fingerprint, n_fingerprint);
		g_free (fingerprint);
	}

	_gcr_display_view_end (view, renderer);
	gck_attributes_unref (attrs);
}
예제 #30
0
static gboolean
collection_method_create_item (GkdExportedCollection *skeleton,
			       GDBusMethodInvocation *invocation,
			       GVariant *properties,
			       GVariant *secret_variant,
			       gboolean replace,
			       GkdSecretObjects *self)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckSession *pkcs11_session = NULL;
	GkdSecretSecret *secret = NULL;
	GckAttributes *attrs = NULL;
	const GckAttribute *fields;
	GckObject *item = NULL;
	const gchar *base;
	GError *error = NULL;
	gchar *path = NULL;
	gchar *identifier;
	gboolean created = FALSE;
	GckObject *object;

	object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
	if (!object) {
		return TRUE;
	}

	if (!gkd_secret_property_parse_all (properties, SECRET_ITEM_INTERFACE, &builder)) {
		g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_INVALID_ARGS,
							       "Invalid properties argument");
		goto cleanup;
	}

	base = g_dbus_method_invocation_get_object_path (invocation);
	secret = gkd_secret_secret_parse (self->service, g_dbus_method_invocation_get_sender (invocation),
					  secret_variant, &error);

	if (secret == NULL) {
		g_dbus_method_invocation_take_error (invocation, error);
		error = NULL;
		goto cleanup;
	}

	if (!gkd_secret_util_parse_path (base, &identifier, NULL))
		g_return_val_if_reached (FALSE);
	g_return_val_if_fail (identifier, FALSE);

	pkcs11_session = gck_object_get_session (object);
	g_return_val_if_fail (pkcs11_session, FALSE);

	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));

	if (replace) {
		fields = gck_attributes_find (attrs, CKA_G_FIELDS);
		if (fields)
			item = collection_find_matching_item (self, pkcs11_session, identifier, fields);
	}

	/* Replace the item */
	if (item) {
		if (!gck_object_set (item, attrs, NULL, &error))
			goto cleanup;

	/* Create a new item */
	} else {
		gck_builder_add_all (&builder, attrs);
		gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier);
		gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
		item = gck_session_create_object (pkcs11_session, gck_builder_end (&builder), NULL, &error);
		if (item == NULL)
			goto cleanup;
		created = TRUE;
	}

	/* Set the secret */
	if (!gkd_secret_session_set_item_secret (secret->session, item, secret, &error)) {
		if (created) /* If we created, then try to destroy on failure */
			gck_object_destroy (item, NULL, NULL);
		goto cleanup;
	}

	path = object_path_for_item (base, item);
	gkd_secret_objects_emit_item_created (self, object, path);

	gkd_exported_collection_complete_create_item (skeleton, invocation, path, "/");

cleanup:
	if (error) {
		if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
			g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
								       GKD_SECRET_ERROR_IS_LOCKED,
								       "Cannot create an item in a locked collection");
		else
			g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_FAILED,
							       "Couldn't create item: %s",
							       egg_error_message (error));
		g_clear_error (&error);
	}

	gkd_secret_secret_free (secret);
	gck_attributes_unref (attrs);
	if (item)
		g_object_unref (item);
	if (pkcs11_session)
		g_object_unref (pkcs11_session);
	g_free (path);
	g_object_unref (object);

	return TRUE;
}