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; }
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; }
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 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; }
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 void add_anchor_to_module (GcrCertificate *certificate, const gchar *purpose) { GckAttributes *attrs; gconstpointer data; gsize n_data; data = gcr_certificate_get_der_data (certificate, &n_data); g_assert (data); /* And add a pinned certificate for the signed certificate */ attrs = gck_attributes_new (); gck_attributes_add_data (attrs, CKA_X_CERTIFICATE_VALUE, data, n_data); gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_X_TRUST_ASSERTION); gck_attributes_add_ulong (attrs, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE); gck_attributes_add_string (attrs, CKA_X_PURPOSE, purpose); gck_mock_module_take_object (attrs); }
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 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 void add_certificate_to_module (GcrCertificate *certificate) { GckAttributes *attrs; gconstpointer data; gsize n_data, n_subject; gpointer subject; data = gcr_certificate_get_der_data (certificate, &n_data); g_assert (data); subject = gcr_certificate_get_subject_raw (certificate, &n_subject); g_assert (subject); /* Add a certificate to the module */ attrs = gck_attributes_new (); gck_attributes_add_data (attrs, CKA_VALUE, data, n_data); gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE); gck_attributes_add_ulong (attrs, CKA_CERTIFICATE_TYPE, CKC_X_509); gck_attributes_add_data (attrs, CKA_SUBJECT, subject, n_subject); gck_mock_module_take_object (attrs); g_free (subject); }
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; }