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;
}
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;
}
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;
}
static void
prepare_generate (SeahorsePkcs11Generate *self)
{
	CK_BYTE rsa_public_exponent[] = { 0x01, 0x00, 0x01 }; /* 65537 in bytes */
	GckBuilder publi = GCK_BUILDER_INIT;
	GckBuilder priva = GCK_BUILDER_INIT;
	const gchar *label;

	g_assert (self->cancellable == NULL);
	g_assert (self->mechanism != NULL);

	gck_builder_add_ulong (&publi, CKA_CLASS, CKO_PUBLIC_KEY);
	gck_builder_add_ulong (&priva, CKA_CLASS, CKO_PRIVATE_KEY);

	gck_builder_add_boolean (&publi, CKA_TOKEN, TRUE);
	gck_builder_add_boolean (&priva, CKA_TOKEN, TRUE);

	gck_builder_add_boolean (&priva, CKA_PRIVATE, TRUE);
	gck_builder_add_boolean (&priva, CKA_SENSITIVE, TRUE);

	label = gtk_entry_get_text (self->label_entry);
	gck_builder_add_string (&publi, CKA_LABEL, label);
	gck_builder_add_string (&priva, CKA_LABEL, label);

	if (self->mechanism->type == CKM_RSA_PKCS_KEY_PAIR_GEN) {
		gck_builder_add_boolean (&publi, CKA_ENCRYPT, TRUE);
		gck_builder_add_boolean (&publi, CKA_VERIFY, TRUE);
		gck_builder_add_boolean (&publi, CKA_WRAP, TRUE);

		gck_builder_add_boolean (&priva, CKA_DECRYPT, TRUE);
		gck_builder_add_boolean (&priva, CKA_SIGN, TRUE);
		gck_builder_add_boolean (&priva, CKA_UNWRAP, TRUE);

		gck_builder_add_data (&publi, CKA_PUBLIC_EXPONENT,
		                      rsa_public_exponent, sizeof (rsa_public_exponent));
		gck_builder_add_ulong (&publi, CKA_MODULUS_BITS,
		                       gtk_spin_button_get_value_as_int (self->bits_entry));

	} else {
		g_warning ("currently no support for this mechanism");
	}

	self->prv_attrs = gck_builder_steal (&priva);
	self->pub_attrs = gck_builder_steal (&publi);

	gck_builder_clear (&publi);
	gck_builder_clear (&priva);
}
Example #5
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;
}
Example #6
0
static void
load_closure_free (gpointer data)
{
	LoadClosure *closure = data;
	g_object_unref (closure->object);
	gck_builder_clear (&closure->builder);
	g_slice_free (LoadClosure, closure);
}
static gboolean
object_property_set (GkdSecretObjects *objects,
		     GckObject *object,
		     const gchar *prop_name,
		     GVariant *value,
		     GError **error_out)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GError *error = NULL;
	gulong attr_type;

	/* What type of property is it? */
	if (!gkd_secret_property_get_type (prop_name, &attr_type)) {
		g_set_error (error_out, G_DBUS_ERROR,
			     G_DBUS_ERROR_UNKNOWN_PROPERTY,
			     "Object does not have the '%s' property",
			     prop_name);
		return FALSE;
	}

	/* Retrieve the actual attribute value */
	if (!gkd_secret_property_parse_variant (value, prop_name, &builder)) {
		gck_builder_clear (&builder);
		g_set_error (error_out, G_DBUS_ERROR,
			     G_DBUS_ERROR_INVALID_ARGS,
			     "The property type or value was invalid: %s",
			     prop_name);
		return FALSE;
	}

	gck_object_set (object, gck_builder_end (&builder), NULL, &error);

	if (error != NULL) {
		if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
			g_set_error (error_out, GKD_SECRET_ERROR,
				     GKD_SECRET_ERROR_IS_LOCKED,
				     "Cannot set property on a locked object");
		else
			g_set_error (error_out, G_DBUS_ERROR,
				     G_DBUS_ERROR_FAILED,
				     "Couldn't set '%s' property: %s",
				     prop_name, egg_error_message (error));
		g_clear_error (&error);
		return FALSE;
	}

	return TRUE;
}
gboolean
gkd_secret_objects_handle_search_items (GkdSecretObjects *self,
					GDBusMethodInvocation *invocation,
					GVariant *attributes,
					const gchar *base,
					gboolean separate_locked)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckObject *search;
	GckSession *session;
	GError *error = NULL;
	gchar *identifier;
	gpointer data;
	gsize n_data;
	GList *locked, *unlocked;
	GList *items;
	GVariantBuilder result;

	if (!gkd_secret_property_parse_fields (attributes, &builder)) {
		gck_builder_clear (&builder);
		g_dbus_method_invocation_return_error_literal (invocation,
							       G_DBUS_ERROR,
							       G_DBUS_ERROR_FAILED,
							       "Invalid data in attributes argument");
		return TRUE;
	}

	if (base != NULL) {
		if (!gkd_secret_util_parse_path (base, &identifier, NULL))
			g_return_val_if_reached (FALSE);
		gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier);
		g_free (identifier);
	}

	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_SEARCH);
	gck_builder_add_boolean (&builder, CKA_TOKEN, FALSE);

	/* The session we're using to access the object */
	session = gkd_secret_service_get_pkcs11_session (self->service, g_dbus_method_invocation_get_sender (invocation));
	g_return_val_if_fail (session, FALSE);

	/* Create the search object */
	search = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error);

	if (error != NULL) {
		g_dbus_method_invocation_return_error (invocation,
						       G_DBUS_ERROR,
						       G_DBUS_ERROR_FAILED,
						       "Couldn't search for items: %s",
						       egg_error_message (error));
		g_clear_error (&error);
		return TRUE;
	}

	/* Get the matched item handles, and delete the search object */
	data = gck_object_get_data (search, CKA_G_MATCHED, NULL, &n_data, &error);
	gck_object_destroy (search, NULL, NULL);
	g_object_unref (search);

	if (error != NULL) {
		g_dbus_method_invocation_return_error (invocation,
						       G_DBUS_ERROR,
						       G_DBUS_ERROR_FAILED,
						       "Couldn't retrieve matched items: %s",
						       egg_error_message (error));
		g_clear_error (&error);
		return TRUE;
	}

	/* Build a list of object handles */
	items = gck_objects_from_handle_array (session, data, n_data / sizeof (CK_OBJECT_HANDLE));
	g_free (data);

	/* Filter out the locked items */
	if (separate_locked) {
		GVariant *unlocked_variant, *locked_variant;

		item_cleanup_search_results (session, items, &locked, &unlocked);

		g_variant_builder_init (&result, G_VARIANT_TYPE ("ao"));
		objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_builder, &result);
		unlocked_variant = g_variant_builder_end (&result);

		g_variant_builder_init (&result, G_VARIANT_TYPE ("ao"));
		objects_foreach_item (self, locked, NULL, on_object_path_append_to_builder, &result);
		locked_variant = g_variant_builder_end (&result);

		g_list_free (locked);
		g_list_free (unlocked);

		g_dbus_method_invocation_return_value (invocation,
						       g_variant_new ("(@ao@ao)",
								      unlocked_variant,
								      locked_variant));
	} else {
		g_variant_builder_init (&result, G_VARIANT_TYPE ("ao"));
		objects_foreach_item (self, items, NULL, on_object_path_append_to_builder, &result);

		g_dbus_method_invocation_return_value (invocation,
						       g_variant_new ("(@ao)", g_variant_builder_end (&result)));
	}

	gck_list_unref_free (items);

	return TRUE;
}
static DBusMessage*
service_method_create_collection (GkdSecretService *self, DBusMessage *message)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	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);
	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_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_builder_clear (&builder);
			return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED,
			                               "Only the 'default' alias is supported");
		}
	}

	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 = 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;
}