void gkm_object_destroy (GkmObject *self, GkmTransaction *transaction) { GkmSession *session; GkmManager *manager; GkmModule *module; g_return_if_fail (GKM_IS_OBJECT (self)); g_return_if_fail (GKM_IS_TRANSACTION (transaction)); g_return_if_fail (!gkm_transaction_get_failed (transaction)); g_return_if_fail (self->pv->module); g_object_ref (self); session = gkm_session_for_session_object (self); if (session != NULL) { gkm_session_destroy_session_object (session, transaction, self); } else { manager = gkm_object_get_manager (self); module = gkm_object_get_module (self); if (manager == gkm_module_get_manager (module)) gkm_module_remove_token_object (module, transaction, self); } /* Forcefully dispose of the object once the transaction completes */ gkm_transaction_add (transaction, NULL, complete_destroy, g_object_ref (self)); g_object_unref (self); }
static GObject* gkm_roots_module_constructor (GType type, guint n_props, GObjectConstructParam *props) { GkmRootsModule *self = GKM_ROOTS_MODULE (G_OBJECT_CLASS (gkm_roots_module_parent_class)->constructor(type, n_props, props)); GkmManager *manager; g_return_val_if_fail (self, NULL); #ifdef ROOT_CERTIFICATES if (!self->directory) self->directory = g_strdup (ROOT_CERTIFICATES); #endif if (self->directory) { self->tracker = gkm_file_tracker_new (self->directory, "*", "*.0"); g_signal_connect (self->tracker, "file-added", G_CALLBACK (file_load), self); g_signal_connect (self->tracker, "file-changed", G_CALLBACK (file_load), self); g_signal_connect (self->tracker, "file-removed", G_CALLBACK (file_remove), self); } manager = gkm_module_get_manager (GKM_MODULE (self)); gkm_manager_add_property_index (manager, "unique", TRUE); gkm_manager_add_property_index (manager, "path", FALSE); return G_OBJECT (self); }
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); }
static GkmObject* factory_create_item (GkmSession *session, GkmTransaction *transaction, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs) { GkmSecretCollection *collection = NULL; GkmSecretItem *item; GkmManager *m_manager; GkmManager *s_manager; CK_ATTRIBUTE *attr; gboolean is_token; gchar *identifier; g_return_val_if_fail (GKM_IS_TRANSACTION (transaction), NULL); g_return_val_if_fail (attrs || !n_attrs, NULL); /* See if a collection attribute was specified */ attr = gkm_attributes_find (attrs, n_attrs, CKA_G_COLLECTION); if (attr == NULL) { gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE); return NULL; } m_manager = gkm_module_get_manager (gkm_session_get_module (session)); s_manager = gkm_session_get_manager (session); gkm_attribute_consume (attr); if (!gkm_attributes_find_boolean (attrs, n_attrs, CKA_TOKEN, &is_token)) collection = gkm_secret_collection_find (session, attr, m_manager, s_manager, NULL); else if (is_token) collection = gkm_secret_collection_find (session, attr, m_manager, NULL); else collection = gkm_secret_collection_find (session, attr, s_manager, NULL); if (!collection) { gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT); return NULL; } /* If an ID was specified, then try and see if that ID already exists */ if (gkm_attributes_find_string (attrs, n_attrs, CKA_ID, &identifier)) { item = gkm_secret_collection_get_item (collection, identifier); if (item == NULL) { gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT); return NULL; } else { gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (item), FALSE, attrs, n_attrs); return g_object_ref (item); } } /* Create a new collection which will own the item */ item = gkm_secret_collection_create_item (collection, transaction); gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (item), TRUE, attrs, n_attrs); return g_object_ref (item); }
static void file_load (GkmFileTracker *tracker, const gchar *path, GkmRootsModule *self) { ParsePrivate ctx; GkmManager *manager; GkmCertificate *cert; guchar *data; GList *objects, *l; GError *error = NULL; gsize n_data; guint num; manager = gkm_module_get_manager (GKM_MODULE (self)); g_return_if_fail (manager); /* Read in the public key */ if (!g_file_get_contents (path, (gchar**)&data, &n_data, &error)) { g_warning ("couldn't load root certificates: %s: %s", path, egg_error_message (error)); return; } memset (&ctx, 0, sizeof (ctx)); ctx.path = path; ctx.module = self; ctx.count = 0; /* Checks for what was at this path */ ctx.checks = g_hash_table_new (g_direct_hash, g_direct_equal); objects = gkm_manager_find_by_string_property (manager, "path", path); for (l = objects; l; l = g_list_next (l)) g_hash_table_insert (ctx.checks, l->data, l->data); g_list_free (objects); /* Try and parse the PEM */ num = egg_openssl_pem_parse (data, n_data, parsed_pem_block, &ctx); /* If no PEM data, try to parse directly as DER */ if (ctx.count == 0) { cert = add_certificate_for_data (self, data, n_data, path); if (cert != NULL) g_hash_table_remove (ctx.checks, cert); } g_hash_table_foreach (ctx.checks, remove_each_certificate, self); g_hash_table_destroy (ctx.checks); g_free (data); }
GkmMate2Storage* gkm_mate2_storage_new (GkmModule *module, const gchar *directory) { GkmManager *manager; g_return_val_if_fail (GKM_IS_MODULE (module), NULL); g_return_val_if_fail (directory, NULL); manager = gkm_module_get_manager (module); g_return_val_if_fail (GKM_IS_MANAGER (manager), NULL); return g_object_new (GKM_TYPE_MATE2_STORAGE, "module", module, "manager", manager, "directory", directory, NULL); }
static void file_remove (GkmFileTracker *tracker, const gchar *path, GkmRootsModule *self) { GList *objects, *l; GkmManager *manager; g_return_if_fail (path); g_return_if_fail (GKM_IS_ROOTS_MODULE (self)); manager = gkm_module_get_manager (GKM_MODULE (self)); g_return_if_fail (manager); objects = gkm_manager_find_by_string_property (manager, "path", path); for (l = objects; l; l = g_list_next (l)) if (!g_hash_table_remove (self->certificates, l->data)) g_return_if_reached (); g_list_free (objects); }
static void gkm_module_get_property (GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) { GkmModule *self = GKM_MODULE (obj); switch (prop_id) { case PROP_MANAGER: g_value_set_object (value, gkm_module_get_manager (self)); break; case PROP_WRITE_PROTECTED: g_value_set_boolean (value, gkm_module_get_write_protected (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; } }
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; }
GkmRootsCertificate* gkm_roots_certificate_new (GkmModule *module, const gchar *unique, const gchar *path) { return g_object_new (GKM_TYPE_ROOTS_CERTIFICATE, "unique", unique, "path", path, "module", module, "manager", gkm_module_get_manager (module), NULL); }
gboolean gkm_credential_for_each (GkmSession *session, GkmObject *object, GkmCredentialFunc func, gpointer user_data) { CK_OBJECT_HANDLE handle; CK_OBJECT_CLASS klass; CK_ATTRIBUTE attrs[2]; GList *results, *l; GkmCredential *cred; gboolean ret; g_return_val_if_fail (GKM_IS_SESSION (session), FALSE); g_return_val_if_fail (GKM_IS_OBJECT (object), FALSE); g_return_val_if_fail (func, FALSE); /* Do we have one right on the session */ cred = gkm_session_get_credential (session); if (cred && gkm_credential_get_object (cred) == object) { g_object_ref (cred); ret = (func) (cred, object, user_data); g_object_unref (cred); if (ret) return TRUE; } klass = CKO_G_CREDENTIAL; attrs[0].type = CKA_CLASS; attrs[0].pValue = &klass; attrs[0].ulValueLen = sizeof (klass); handle = gkm_object_get_handle (object); attrs[1].type = CKA_G_OBJECT; attrs[1].pValue = &handle; attrs[1].ulValueLen = sizeof (handle); /* Find any on the session */ results = gkm_manager_find_by_attributes (gkm_session_get_manager (session), session, attrs, G_N_ELEMENTS (attrs)); for (l = results; l; l = g_list_next (l)) { g_object_ref (l->data); ret = (func) (l->data, object, user_data); g_object_unref (l->data); if (ret) break; } g_list_free (results); if (l != NULL) return TRUE; /* Find any in the token */ results = gkm_manager_find_by_attributes (gkm_module_get_manager (gkm_session_get_module (session)), session, attrs, G_N_ELEMENTS (attrs)); for (l = results; l; l = g_list_next (l)) { g_object_ref (l->data); ret = (func) (l->data, object, user_data); g_object_unref (l->data); if (ret) break; } g_list_free (results); return (l != NULL); }
GkmSshPrivateKey* gkm_ssh_private_key_new (GkmModule *module, const gchar *unique) { return g_object_new (GKM_TYPE_SSH_PRIVATE_KEY, "unique", unique, "module", module, "manager", gkm_module_get_manager (module), NULL); }