static void gkm_user_module_init (GkmUserModule *self) { self->unlocked_apps = g_hash_table_new_full (gkm_util_ulong_hash, gkm_util_ulong_equal, gkm_util_ulong_free, NULL); /* Our default token info, updated as module runs */ memcpy (&self->token_info, &user_module_token_info, sizeof (CK_TOKEN_INFO)); /* For creating stored keys */ gkm_module_register_factory (GKM_MODULE (self), GKM_FACTORY_USER_PRIVATE_KEY); gkm_module_register_factory (GKM_MODULE (self), GKM_FACTORY_USER_PUBLIC_KEY); }
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 gkm_module_finalize (GObject *obj) { GkmModule *self = GKM_MODULE (obj); g_hash_table_destroy (self->pv->transient_objects); self->pv->transient_objects = NULL; g_object_unref (self->pv->transient_store); self->pv->transient_store = NULL; g_assert (self->pv->token_manager == NULL); g_assert (g_hash_table_size (self->pv->apartments_by_id) == 0); g_hash_table_destroy (self->pv->apartments_by_id); self->pv->apartments_by_id = NULL; g_assert (g_hash_table_size (self->pv->sessions_by_handle) == 0); g_hash_table_destroy (self->pv->sessions_by_handle); self->pv->sessions_by_handle = NULL; g_array_free (self->pv->factories, TRUE); self->pv->factories = NULL; gkm_timer_shutdown (); G_OBJECT_CLASS (gkm_module_parent_class)->finalize (obj); }
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; }
static GObject* gkm_user_module_constructor (GType type, guint n_props, GObjectConstructParam *props) { GkmUserModule *self = GKM_USER_MODULE (G_OBJECT_CLASS (gkm_user_module_parent_class)->constructor(type, n_props, props)); g_return_val_if_fail (self, NULL); if (!self->directory) self->directory = g_build_filename (g_get_home_dir (), ".mate2", "keyrings", NULL); self->storage = gkm_user_storage_new (GKM_MODULE (self), self->directory); return G_OBJECT (self); }
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); }
static GObject* gkm_module_constructor (GType type, guint n_props, GObjectConstructParam *props) { GkmModule *self = GKM_MODULE (G_OBJECT_CLASS (gkm_module_parent_class)->constructor(type, n_props, props)); CK_ATTRIBUTE attr; g_return_val_if_fail (self, NULL); /* Register store attributes */ attr.type = CKA_LABEL; attr.pValue = ""; attr.ulValueLen = 0; gkm_store_register_schema (self->pv->transient_store, &attr, NULL, 0); return G_OBJECT (self); }
static void gkm_module_dispose (GObject *obj) { GkmModule *self = GKM_MODULE (obj); g_hash_table_remove_all (self->pv->transient_objects); g_hash_table_remove_all (self->pv->sessions_by_handle); g_hash_table_remove_all (self->pv->apartments_by_id); if (self->pv->token_manager) g_object_unref (self->pv->token_manager); self->pv->token_manager = NULL; g_array_set_size (self->pv->factories, 0); G_OBJECT_CLASS (gkm_module_parent_class)->dispose (obj); }
static void file_load (EggFileTracker *tracker, const gchar *path, GkmSshModule *self) { GkmSshPrivateKey *key; gchar *private_path; GError *error = NULL; gchar *unique; g_return_if_fail (path); g_return_if_fail (GKM_IS_SSH_MODULE (self)); private_path = private_path_for_public (path); if (!private_path || !g_file_test (private_path, G_FILE_TEST_IS_REGULAR)) { g_message ("no private key present for public key: %s", path); g_free (private_path); return; } /* Create a key if necessary */ key = g_hash_table_lookup (self->keys_by_path, path); if (key == NULL) { unique = g_strdup_printf ("ssh-store:%s", private_path); key = gkm_ssh_private_key_new (GKM_MODULE (self), unique); g_free (unique); g_hash_table_replace (self->keys_by_path, g_strdup (path), key); } /* Parse the data into the key */ if (!gkm_ssh_private_key_parse (key, path, private_path, &error)) { if (error) { g_message ("couldn't parse data: %s: %s", path, egg_error_message (error)); g_clear_error (&error); } gkm_object_expose (GKM_OBJECT (key), FALSE); /* When successful register with the object manager */ } else { gkm_object_expose (GKM_OBJECT (key), TRUE); } g_free (private_path); }
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 void gkm_module_set_property (GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) { GkmModule *self = GKM_MODULE (obj); CK_C_INITIALIZE_ARGS_PTR args; switch (prop_id) { case PROP_INITIALIZE_ARGS: args = g_value_get_pointer (value); if (args != NULL && args->pReserved != NULL) parse_arguments (self, args->pReserved); break; case PROP_MUTEX: self->pv->mutex = g_value_get_pointer (value); g_return_if_fail (self->pv->mutex); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; } }