Пример #1
0
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;
}
Пример #2
0
/**
 * 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);
}
Пример #3
0
/**
 * 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;
}
Пример #4
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);
}
Пример #5
0
/**
 * 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);
}
Пример #6
0
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));
}
Пример #7
0
/**
 * 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);
}
Пример #8
0
/**
 * 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;

}
Пример #9
0
/**
 * 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;
}
Пример #10
0
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);
}
Пример #11
0
/**
 * 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;
}
Пример #12
0
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);
}
Пример #13
0
/**
 * 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;
}
Пример #14
0
/**
 * 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;
}