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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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); }
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); }
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; }
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); }
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 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; } }
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; }
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; }
/** * 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)); }
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 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); } } }
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); }
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); }
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; }
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; }
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); }
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; }
/** * 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; }
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); }
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; }