static GckSession* open_and_login_session (GckSlot *slot, CK_USER_TYPE user_type, GError **error) { GckSession *session; GError *err = NULL; g_return_val_if_fail (GCK_IS_SLOT (slot), NULL); if (!error) error = &err; session = gck_slot_open_session (slot, GCK_SESSION_READ_WRITE, NULL, error); if (session != NULL) { if (!gck_session_login (session, user_type, NULL, 0, NULL, error)) { if (g_error_matches (*error, GCK_ERROR, CKR_USER_ALREADY_LOGGED_IN)) { g_clear_error (error); } else { g_object_unref (session); session = NULL; } } } return session; }
/** * gck_slot_get_module: * @self: The slot to get the module for. * * Get the module that this slot is on. * * Return value: The module, you must unreference this after you're done with it. */ GckModule* gck_slot_get_module (GckSlot *self) { g_return_val_if_fail (GCK_IS_SLOT (self), NULL); g_return_val_if_fail (GCK_IS_MODULE (self->pv->module), NULL); return g_object_ref (self->pv->module); }
/** * gck_slot_has_flags: * @self: The GckSlot object. * @flags: The flags to check. * * Check if the PKCS11 slot has the given flags. * * Returns: Whether one or more flags exist. */ gboolean gck_slot_has_flags (GckSlot *self, gulong flags) { CK_FUNCTION_LIST_PTR funcs; GckModule *module = NULL; CK_TOKEN_INFO info; CK_SLOT_ID handle; CK_RV rv; g_return_val_if_fail (GCK_IS_SLOT (self), FALSE); g_object_get (self, "module", &module, "handle", &handle, NULL); g_return_val_if_fail (GCK_IS_MODULE (module), FALSE); funcs = gck_module_get_functions (module); g_return_val_if_fail (funcs, FALSE); memset (&info, 0, sizeof (info)); rv = (funcs->C_GetTokenInfo) (handle, &info); g_object_unref (module); if (rv != CKR_OK) { g_warning ("couldn't get slot info: %s", gck_message_from_rv (rv)); return FALSE; } return (info.flags & flags) != 0; }
/** * gck_slot_equal: * @slot1: A pointer to the first GckSlot * @slot2: A pointer to the second GckSlot * * Checks equality of two slots. Two GckSlot objects can point to the same * underlying PKCS#11 slot. * * Return value: TRUE if slot1 and slot2 are equal. FALSE if either is not a GckSlot. **/ gboolean gck_slot_equal (gconstpointer slot1, gconstpointer slot2) { GckSlot *s1, *s2; if (slot1 == slot2) return TRUE; if (!GCK_IS_SLOT (slot1) || !GCK_IS_SLOT (slot2)) return FALSE; s1 = GCK_SLOT (slot1); s2 = GCK_SLOT (slot2); return s1->pv->handle == s2->pv->handle && gck_module_equal (s1->pv->module, s2->pv->module); }
/** * gck_password_get_token: * @self: the password object * * If the password request is to unlock a PKCS\#11 token, then this is the * slot containing that token. * * Returns: (transfer full): the slot that contains the token, or %NULL if not * being requested for a token; must be unreferenced after use */ GckSlot * gck_password_get_token (GckPassword *self) { g_return_val_if_fail (GCK_IS_PASSWORD (self), NULL); if (!self->pv->for_token) return NULL; g_return_val_if_fail (GCK_IS_SLOT (self->pv->token_or_key), NULL); return g_object_ref (self->pv->token_or_key); }
static void gck_password_constructed (GObject *obj) { GckPassword *self = GCK_PASSWORD (obj); G_OBJECT_CLASS (gck_password_parent_class)->constructed (obj); g_return_if_fail (GCK_IS_SLOT (self->pv->token_or_key) || GCK_IS_OBJECT (self->pv->token_or_key)); }
/** * gck_slot_hash: * @slot: A pointer to a GckSlot * * Create a hash value for the GckSlot. * * This function is intended for easily hashing a GckSlot to add to * a GHashTable or similar data structure. * * Return value: An integer that can be used as a hash value, or 0 if invalid. **/ guint gck_slot_hash (gconstpointer slot) { GckSlot *self; g_return_val_if_fail (GCK_IS_SLOT (slot), 0); self = GCK_SLOT (slot); return _gck_ulong_hash (&self->pv->handle) ^ gck_module_hash (self->pv->module); }
/** * gck_slot_get_mechanisms: * @self: The slot to get mechanisms for. * * Get the available mechanisms for this slot. * * Return value: A list of the mechanisms for this slot. Use * gck_mechanisms_free() when done with this. **/ GckMechanisms* gck_slot_get_mechanisms (GckSlot *self) { CK_SLOT_ID handle = (CK_SLOT_ID)-1; CK_FUNCTION_LIST_PTR funcs; GckModule *module = NULL; CK_MECHANISM_TYPE_PTR mech_list = NULL; CK_ULONG count, i; GckMechanisms *result; CK_RV rv; g_return_val_if_fail (GCK_IS_SLOT (self), NULL); g_object_get (self, "module", &module, "handle", &handle, NULL); g_return_val_if_fail (GCK_IS_MODULE (module), NULL); funcs = gck_module_get_functions (module); g_return_val_if_fail (funcs, NULL); rv = (funcs->C_GetMechanismList) (handle, NULL, &count); if (rv != CKR_OK) { g_warning ("couldn't get mechanism count: %s", gck_message_from_rv (rv)); count = 0; } else { mech_list = g_new (CK_MECHANISM_TYPE, count); rv = (funcs->C_GetMechanismList) (handle, mech_list, &count); if (rv != CKR_OK) { g_warning ("couldn't get mechanism list: %s", gck_message_from_rv (rv)); g_free (mech_list); count = 0; } } g_object_unref (module); if (!count) return NULL; result = g_array_new (FALSE, TRUE, sizeof (CK_MECHANISM_TYPE)); for (i = 0; i < count; ++i) g_array_append_val (result, mech_list[i]); g_free (mech_list); return result; }
/** * gck_slot_get_info: * @self: The slot to get info for. * * Get the information for this slot. * * Return value: The slot information. When done, use gck_slot_info_free() * to release it. **/ GckSlotInfo* gck_slot_get_info (GckSlot *self) { CK_SLOT_ID handle = (CK_SLOT_ID)-1; GckModule *module = NULL; CK_FUNCTION_LIST_PTR funcs; GckSlotInfo *slotinfo; CK_SLOT_INFO info; CK_RV rv; g_return_val_if_fail (GCK_IS_SLOT (self), NULL); g_object_get (self, "module", &module, "handle", &handle, NULL); g_return_val_if_fail (GCK_IS_MODULE (module), NULL); funcs = gck_module_get_functions (module); g_return_val_if_fail (funcs, NULL); memset (&info, 0, sizeof (info)); rv = (funcs->C_GetSlotInfo) (handle, &info); g_object_unref (module); if (rv != CKR_OK) { g_warning ("couldn't get slot info: %s", gck_message_from_rv (rv)); return NULL; } slotinfo = g_new0 (GckSlotInfo, 1); slotinfo->slot_description = gck_string_from_chars (info.slotDescription, sizeof (info.slotDescription)); slotinfo->manufacturer_id = gck_string_from_chars (info.manufacturerID, sizeof (info.manufacturerID)); slotinfo->flags = info.flags; slotinfo->hardware_version_major = info.hardwareVersion.major; slotinfo->hardware_version_minor = info.hardwareVersion.minor; slotinfo->firmware_version_major = info.firmwareVersion.major; slotinfo->firmware_version_minor = info.firmwareVersion.minor; return slotinfo; }
static GObject* gkd_secret_service_constructor (GType type, guint n_props, GObjectConstructParam *props) { GkdSecretService *self = GKD_SECRET_SERVICE (G_OBJECT_CLASS (gkd_secret_service_parent_class)->constructor(type, n_props, props)); DBusError error = DBUS_ERROR_INIT; GckSlot *slot = NULL; guint i; g_return_val_if_fail (self, NULL); g_return_val_if_fail (self->connection, NULL); /* Find the pkcs11-slot parameter */ for (i = 0; !slot && i < n_props; ++i) { if (g_str_equal (props[i].pspec->name, "pkcs11-slot")) slot = g_value_get_object (props[i].value); } /* Create our objects proxy */ g_return_val_if_fail (GCK_IS_SLOT (slot), NULL); self->objects = g_object_new (GKD_SECRET_TYPE_OBJECTS, "pkcs11-slot", slot, "service", self, NULL); /* Register for signals that let us know when clients leave the bus */ self->match_rule = g_strdup_printf ("type='signal',member=NameOwnerChanged," "interface='" DBUS_INTERFACE_DBUS "'"); dbus_bus_add_match (self->connection, self->match_rule, &error); if (dbus_error_is_set (&error)) { g_warning ("couldn't listen for NameOwnerChanged signal on session bus: %s", error.message); dbus_error_free (&error); g_free (self->match_rule); self->match_rule = NULL; } if (!dbus_connection_add_filter (self->connection, gkd_secret_service_filter_handler, self, NULL)) g_return_val_if_reached (NULL); return G_OBJECT (self); }
/** * gck_slot_get_mechanism_info: * @self: The slot to get mechanism info from. * @mech_type: The mechanisms type to get info for. * * Get information for the specified mechanism. * * Return value: The mechanism information, or NULL if failed. Use * gck_mechanism_info_free() when done with it. **/ GckMechanismInfo* gck_slot_get_mechanism_info (GckSlot *self, gulong mech_type) { CK_SLOT_ID handle = (CK_SLOT_ID)-1; CK_FUNCTION_LIST_PTR funcs; GckMechanismInfo *mechinfo; GckModule *module = NULL; CK_MECHANISM_INFO info; struct tm; CK_RV rv; g_return_val_if_fail (GCK_IS_SLOT (self), NULL); g_object_get (self, "module", &module, "handle", &handle, NULL); g_return_val_if_fail (GCK_IS_MODULE (module), NULL); funcs = gck_module_get_functions (module); g_return_val_if_fail (funcs, NULL); memset (&info, 0, sizeof (info)); rv = (funcs->C_GetMechanismInfo) (handle, mech_type, &info); g_object_unref (module); if (rv != CKR_OK) { g_warning ("couldn't get mechanism info: %s", gck_message_from_rv (rv)); return NULL; } mechinfo = g_new0 (GckMechanismInfo, 1); mechinfo->flags = info.flags; mechinfo->max_key_size = info.ulMaxKeySize; mechinfo->min_key_size = info.ulMinKeySize; return mechinfo; }
static GObject* gkd_secret_service_constructor (GType type, guint n_props, GObjectConstructParam *props) { GkdSecretService *self = GKD_SECRET_SERVICE (G_OBJECT_CLASS (gkd_secret_service_parent_class)->constructor(type, n_props, props)); GError *error = NULL; GckSlot *slot = NULL; guint i; g_return_val_if_fail (self, NULL); g_return_val_if_fail (self->connection, NULL); /* Find the pkcs11-slot parameter */ for (i = 0; !slot && i < n_props; ++i) { if (g_str_equal (props[i].pspec->name, "pkcs11-slot")) slot = g_value_get_object (props[i].value); } /* Create our objects proxy */ g_return_val_if_fail (GCK_IS_SLOT (slot), NULL); self->objects = g_object_new (GKD_SECRET_TYPE_OBJECTS, "pkcs11-slot", slot, "service", self, NULL); self->skeleton = gkd_secret_service_skeleton_new (self); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->skeleton), self->connection, SECRET_SERVICE_PATH, &error); if (error != NULL) { g_warning ("could not register secret service on session bus: %s", error->message); g_clear_error (&error); } g_signal_connect (self->skeleton, "handle-change-lock", G_CALLBACK (service_method_change_lock), self); g_signal_connect (self->skeleton, "handle-create-collection", G_CALLBACK (service_method_create_collection), self); g_signal_connect (self->skeleton, "handle-get-secrets", G_CALLBACK (service_method_get_secrets), self); g_signal_connect (self->skeleton, "handle-lock", G_CALLBACK (service_method_lock), self); g_signal_connect (self->skeleton, "handle-lock-service", G_CALLBACK (service_method_lock_service), self); g_signal_connect (self->skeleton, "handle-open-session", G_CALLBACK (service_method_open_session), self); g_signal_connect (self->skeleton, "handle-read-alias", G_CALLBACK (service_method_read_alias), self); g_signal_connect (self->skeleton, "handle-search-items", G_CALLBACK (service_method_search_items), self); g_signal_connect (self->skeleton, "handle-set-alias", G_CALLBACK (service_method_set_alias), self); g_signal_connect (self->skeleton, "handle-unlock", G_CALLBACK (service_method_unlock), self); self->internal_skeleton = gkd_exported_internal_skeleton_new (); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->internal_skeleton), self->connection, SECRET_SERVICE_PATH, &error); if (error != NULL) { g_warning ("could not register internal interface service on session bus: %s", error->message); g_clear_error (&error); } g_signal_connect (self->internal_skeleton, "handle-change-with-master-password", G_CALLBACK (service_method_change_with_master_password), self); g_signal_connect (self->internal_skeleton, "handle-change-with-prompt", G_CALLBACK (service_method_change_with_prompt), self); g_signal_connect (self->internal_skeleton, "handle-create-with-master-password", G_CALLBACK (service_method_create_with_master_password), self); g_signal_connect (self->internal_skeleton, "handle-unlock-with-master-password", G_CALLBACK (service_method_unlock_with_master_password), self); self->name_owner_id = g_dbus_connection_signal_subscribe (self->connection, NULL, "org.freedesktop.DBus", "NameOwnerChanged", NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE, service_name_owner_changed, self, NULL); self->filter_id = g_dbus_connection_add_filter (self->connection, service_message_filter, self, NULL); gkd_secret_service_init_collections (self); return G_OBJECT (self); }
/** * gck_slot_get_token_info: * @self: The slot to get info for. * * Get the token information for this slot. * * Return value: The token information. When done, use gck_token_info_free() * to release it. **/ GckTokenInfo* gck_slot_get_token_info (GckSlot *self) { CK_SLOT_ID handle = (CK_SLOT_ID)-1; CK_FUNCTION_LIST_PTR funcs; GckModule *module = NULL; GckTokenInfo *tokeninfo; CK_TOKEN_INFO info; gchar *string; struct tm tm; CK_RV rv; g_return_val_if_fail (GCK_IS_SLOT (self), NULL); g_object_get (self, "module", &module, "handle", &handle, NULL); g_return_val_if_fail (GCK_IS_MODULE (module), NULL); funcs = gck_module_get_functions (module); g_return_val_if_fail (funcs, NULL); memset (&info, 0, sizeof (info)); rv = (funcs->C_GetTokenInfo) (handle, &info); g_object_unref (module); if (rv != CKR_OK) { g_warning ("couldn't get slot info: %s", gck_message_from_rv (rv)); return NULL; } tokeninfo = g_new0 (GckTokenInfo, 1); tokeninfo->label = gck_string_from_chars (info.label, sizeof (info.label)); tokeninfo->model = gck_string_from_chars (info.model, sizeof (info.model)); tokeninfo->manufacturer_id = gck_string_from_chars (info.manufacturerID, sizeof (info.manufacturerID)); tokeninfo->serial_number = gck_string_from_chars (info.serialNumber, sizeof (info.serialNumber)); tokeninfo->flags = info.flags; tokeninfo->max_session_count = info.ulMaxSessionCount; tokeninfo->session_count = info.ulSessionCount; tokeninfo->max_rw_session_count = info.ulMaxRwSessionCount; tokeninfo->rw_session_count = info.ulRwSessionCount; tokeninfo->max_pin_len = info.ulMaxPinLen; tokeninfo->min_pin_len = info.ulMinPinLen; tokeninfo->total_public_memory = info.ulTotalPublicMemory; tokeninfo->total_private_memory = info.ulTotalPrivateMemory; tokeninfo->free_private_memory = info.ulFreePrivateMemory; tokeninfo->free_public_memory = info.ulFreePublicMemory; tokeninfo->hardware_version_major = info.hardwareVersion.major; tokeninfo->hardware_version_minor = info.hardwareVersion.minor; tokeninfo->firmware_version_major = info.firmwareVersion.major; tokeninfo->firmware_version_minor = info.firmwareVersion.minor; /* Parse the time into seconds since epoch */ if (info.flags & CKF_CLOCK_ON_TOKEN) { string = g_strndup ((gchar*)info.utcTime, MIN (14, sizeof (info.utcTime))); if (!strptime (string, "%Y%m%d%H%M%S", &tm)) tokeninfo->utc_time = -1; else tokeninfo->utc_time = timegm (&tm); g_free (string); } else { tokeninfo->utc_time = -1; } return tokeninfo; }
/** * gck_slot_get_handle: * @self: The slot to get the handle of. * * Get the raw PKCS#11 handle of a slot. * * Return value: The raw handle. **/ CK_SLOT_ID gck_slot_get_handle (GckSlot *self) { g_return_val_if_fail (GCK_IS_SLOT (self), (CK_SLOT_ID)-1); return self->pv->handle; }