Exemplo n.º 1
0
static void
data_file_entry_added (GkmMate2File *store, const gchar *identifier, GkmMate2Storage *self)
{
    GError *error = NULL;
    GkmObject *object;
    gboolean ret;
    guchar *data;
    gsize n_data;
    GType type;
    gchar *path;

    g_return_if_fail (GKM_IS_MATE2_STORAGE (self));
    g_return_if_fail (identifier);

    /* Already have this object? */
    object = g_hash_table_lookup (self->identifier_to_object, identifier);
    if (object != NULL)
        return;

    /* Figure out what type of object we're dealing with */
    type = type_from_identifier (identifier);
    if (type == 0) {
        g_warning ("don't know how to load file in user store: %s", identifier);
        return;
    }

    /* Read the file in */
    path = g_build_filename (self->directory, identifier, NULL);
    ret = g_file_get_contents (path, (gchar**)&data, &n_data, &error);
    g_free (path);

    if (ret == FALSE) {
        g_warning ("couldn't read file in user store: %s: %s", identifier,
                   egg_error_message (error));
        g_clear_error (&error);
        return;
    }

    /* Make sure that the object wasn't tampered with */
    if (!check_object_hash (self, identifier, data, n_data)) {
        g_message ("file in user store doesn't match hash: %s", identifier);
        return;
    }

    /* Create a new object for this identifier */
    object = g_object_new (type, "unique", identifier, "module", self->module,
                           "manager", gkm_module_get_manager (self->module), NULL);
    g_return_if_fail (GKM_IS_SERIALIZABLE (object));
    g_return_if_fail (GKM_SERIALIZABLE_GET_INTERFACE (object)->extension);

    /* And load the data into it */
    if (gkm_serializable_load (GKM_SERIALIZABLE (object), self->login, data, n_data))
        take_object_ownership (self, identifier, object);
    else
        g_message ("failed to load file in user store: %s", identifier);

    g_free (data);
    g_object_unref (object);
}
Exemplo n.º 2
0
static GkmCertificate*
add_certificate_for_data (GkmRootsModule *self, const guchar *data,
                          gsize n_data, const gchar *path)
{
	GkmCertificate *cert;
	GkmManager *manager;
	gchar *hash, *unique;

	g_assert (GKM_IS_ROOTS_MODULE (self));
	g_assert (data);
	g_assert (path);

	manager = gkm_module_get_manager (GKM_MODULE (self));
	g_return_val_if_fail (manager, NULL);

	/* Hash the certificate */
	hash = g_compute_checksum_for_data (G_CHECKSUM_MD5, data, n_data);
	unique = g_strdup_printf ("%s:%s", path, hash);
	g_free (hash);

	/* Try and find a certificate */
	cert = GKM_CERTIFICATE (gkm_manager_find_one_by_string_property (manager, "unique", unique));
	if (cert != NULL) {
		g_free (unique);
		return cert;
	}

	/* Create a new certificate object */
	cert = GKM_CERTIFICATE (gkm_roots_certificate_new (GKM_MODULE (self), unique, path));
	g_free (unique);

	if (!gkm_serializable_load (GKM_SERIALIZABLE (cert), NULL, data, n_data)) {
		g_message ("couldn't parse certificate(s): %s", path);
		g_object_unref (cert);
		return NULL;
	}

	/* Make the certificate show up */
	gkm_object_expose (GKM_OBJECT (cert), TRUE);

	/* And add to our wonderful table */
	g_hash_table_insert (self->certificates, cert, cert);
	return cert;
}
Exemplo n.º 3
0
static GkmObject*
factory_create_certificate (GkmSession *session, GkmTransaction *transaction,
                            CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
	CK_ATTRIBUTE_PTR attr;
	GkmCertificate *cert;

	g_return_val_if_fail (GKM_IS_TRANSACTION (transaction), NULL);
	g_return_val_if_fail (attrs || !n_attrs, NULL);

	/* Dig out the value */
	attr = gkm_attributes_find (attrs, n_attrs, CKA_VALUE);
	if (attr == NULL) {
		gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
		return NULL;
	}

	cert = g_object_new (GKM_TYPE_CERTIFICATE,
	                     "module", gkm_session_get_module (session),
	                     "manager", gkm_manager_for_template (attrs, n_attrs, session),
	                     NULL);

	/* Load the certificate from the data specified */
	if (!gkm_serializable_load (GKM_SERIALIZABLE (cert), NULL, attr->pValue, attr->ulValueLen)) {
		gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
		g_object_unref (cert);
		return NULL;
	}

	/* Note that we ignore the subject */
	gkm_attributes_consume (attrs, n_attrs, CKA_VALUE, CKA_SUBJECT, G_MAXULONG);

	gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (cert),
	                                      TRUE, attrs, n_attrs);
	return GKM_OBJECT (cert);
}
Exemplo n.º 4
0
static void
relock_object (GkmMate2Storage *self, GkmTransaction *transaction, const gchar *path,
               const gchar *identifier, GkmSecret *old_login, GkmSecret *new_login)
{
    GError *error = NULL;
    GkmObject *object;
    gpointer data;
    gsize n_data;
    GType type;

    g_assert (GKM_IS_MATE2_STORAGE (self));
    g_assert (GKM_IS_TRANSACTION (transaction));
    g_assert (identifier);
    g_assert (path);

    g_assert (!gkm_transaction_get_failed (transaction));

    /* Figure out the type of object */
    type = type_from_identifier (identifier);
    if (type == 0) {
        g_warning ("don't know how to relock file in user store: %s", identifier);
        gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
        return;
    }

    /* Create a dummy object for this identifier */
    object = g_object_new (type, "unique", identifier, "module", self->module, NULL);
    if (!GKM_IS_SERIALIZABLE (object)) {
        g_warning ("cannot relock unserializable object for file in user store: %s", identifier);
        gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
        return;
    }

    /* Read in the data for the object */
    if (!g_file_get_contents (path, (gchar**)&data, &n_data, &error)) {
        g_message ("couldn't load file in user store in order to relock: %s: %s", identifier,
                   egg_error_message (error));
        g_clear_error (&error);
        g_object_unref (object);
        gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
        return;
    }

    /* Make sure the data matches the hash */
    if (!check_object_hash (self, identifier, data, n_data)) {
        g_message ("file in data store doesn't match hash: %s", identifier);
        gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
        return;
    }

    /* Load it into our temporary object */
    if (!gkm_serializable_load (GKM_SERIALIZABLE (object), old_login, data, n_data)) {
        g_message ("unrecognized or invalid user store file: %s", identifier);
        gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
        g_free (data);
        g_object_unref (object);
        return;
    }

    g_free (data);
    data = NULL;

    /* Read it out of our temporary object */
    if (!gkm_serializable_save (GKM_SERIALIZABLE (object), new_login, &data, &n_data)) {
        g_warning ("unable to serialize data with new login: %s", identifier);
        gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
        g_object_unref (object);
        g_free (data);
        return;
    }

    g_object_unref (object);

    /* And write it back out to the file */
    gkm_transaction_write_file (transaction, path, data, n_data);

    /* Create and save the hash here */
    if (!gkm_transaction_get_failed (transaction))
        store_object_hash (self, transaction, identifier, data, n_data);

    g_free (data);

}
Exemplo n.º 5
0
void
gkm_mate2_storage_create (GkmMate2Storage *self, GkmTransaction *transaction, GkmObject *object)
{
    gboolean is_private;
    GkmDataResult res;
    gchar *identifier;
    gpointer data;
    gsize n_data;
    gchar *path;

    g_return_if_fail (GKM_IS_MATE2_STORAGE (self));
    g_return_if_fail (GKM_IS_TRANSACTION (transaction));
    g_return_if_fail (!gkm_transaction_get_failed (transaction));
    g_return_if_fail (GKM_IS_OBJECT (object));

    /* Make sure we haven't already stored it */
    identifier = g_hash_table_lookup (self->object_to_identifier, object);
    g_return_if_fail (identifier == NULL);

    /* Double check that the object is in fact serializable */
    if (!GKM_IS_SERIALIZABLE (object)) {
        g_warning ("can't store object of type '%s' on token", G_OBJECT_TYPE_NAME (object));
        gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
        g_return_if_reached ();
    }

    /* Figure out whether this is a private object */
    if (!gkm_object_get_attribute_boolean (object, NULL, CKA_PRIVATE, &is_private))
        is_private = FALSE;

    /* Can't serialize private if we're not unlocked */
    if (is_private && !self->login) {
        gkm_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN);
        return;
    }

    /* Hook ourselves into the transaction */
    if (!begin_modification_state (self, transaction))
        return;

    /* Create an identifier guaranteed unique by this transaction */
    identifier = identifier_for_object (object);
    if (gkm_mate2_file_unique_entry (self->file, &identifier) != GKM_DATA_SUCCESS) {
        gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
        g_return_if_reached ();
    }

    /* We don't want to get signals about this item being added */
    g_signal_handlers_block_by_func (self->file, data_file_entry_added, self);
    g_signal_handlers_block_by_func (self->file, data_file_entry_changed, self);

    res = gkm_mate2_file_create_entry (self->file, identifier,
                                       is_private ? GKM_MATE2_FILE_SECTION_PRIVATE : GKM_MATE2_FILE_SECTION_PUBLIC);

    g_signal_handlers_unblock_by_func (self->file, data_file_entry_added, self);
    g_signal_handlers_unblock_by_func (self->file, data_file_entry_changed, self);

    switch(res) {
    case GKM_DATA_FAILURE:
    case GKM_DATA_UNRECOGNIZED:
        g_free (identifier);
        gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
        return;
    case GKM_DATA_LOCKED:
        g_free (identifier);
        gkm_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN);
        return;
    case GKM_DATA_SUCCESS:
        break;
    default:
        g_assert_not_reached ();
    }

    /* Serialize the object in question */
    if (!gkm_serializable_save (GKM_SERIALIZABLE (object), is_private ? self->login : NULL, &data, &n_data)) {
        gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
        g_return_if_reached ();
    }

    path = g_build_filename (self->directory, identifier, NULL);
    gkm_transaction_write_file (transaction, path, data, n_data);

    /* Make sure we write in the object hash */
    if (!gkm_transaction_get_failed (transaction))
        store_object_hash (self, transaction, identifier, data, n_data);

    /* Now we decide to own the object */
    if (!gkm_transaction_get_failed (transaction))
        take_object_ownership (self, identifier, object);

    g_free (identifier);
    g_free (path);
    g_free (data);
}