Esempio n. 1
0
gboolean
gkd_secret_lock (GckObject *collection, DBusError *derr)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GError *error = NULL;
	GList *objects, *l;
	GckSession *session;

	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_CREDENTIAL);
	gck_builder_add_ulong (&builder, CKA_G_OBJECT, gck_object_get_handle (collection));

	session = gck_object_get_session (collection);
	g_return_val_if_fail (session, FALSE);

	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);

	g_object_unref (session);

	if (error != NULL) {
		g_warning ("couldn't search for credential objects: %s", egg_error_message (error));
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't lock collection");
		g_clear_error (&error);
		return FALSE;
	}

	for (l = objects; l; l = g_list_next (l)) {
		if (!gck_object_destroy (l->data, NULL, &error)) {
			g_warning ("couldn't destroy credential object: %s", egg_error_message (error));
			g_clear_error (&error);
		}
	}

	gck_list_unref_free (objects);
	return TRUE;
}
GckSession*
gkd_secret_service_internal_pkcs11_session (GkdSecretService *self)
{
	GError *error = NULL;
	GckSlot *slot;

	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);

	if (self->internal_session)
		return self->internal_session;

	slot = gkd_secret_service_get_pkcs11_slot (self);
	self->internal_session = gck_slot_open_session_full (slot, GCK_SESSION_READ_WRITE,
							     0, NULL, NULL, NULL, &error);
	if (!self->internal_session) {
		g_warning ("couldn't open pkcs11 session for secret service: %s",
			   egg_error_message (error));
		g_clear_error (&error);
		return NULL;
	}

	if (!log_into_pkcs11_session (self->internal_session, &error)) {
		g_warning ("couldn't log in to pkcs11 session for secret service: %s",
			   egg_error_message (error));
		g_clear_error (&error);
		g_object_unref (self->internal_session);
		self->internal_session = NULL;
		return NULL;
	}

	return self->internal_session;
}
Esempio n. 3
0
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;
}
void
gkd_secret_objects_foreach_collection (GkdSecretObjects *self,
				       const gchar *caller,
				       GkdSecretObjectsForeach callback,
				       gpointer user_data)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckSession *session;
	GError *error = NULL;
	GList *collections, *l;
	gpointer identifier;
	gsize n_identifier;
	gchar *path;

	g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
	g_return_if_fail (callback);

	/* The session we're using to access the object */
	if (caller == NULL) {
		session = gkd_secret_service_internal_pkcs11_session (self->service);
	} else {
		session = gkd_secret_service_get_pkcs11_session (self->service, caller);
	}

	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION);

	collections = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);

	if (error != NULL) {
		g_warning ("couldn't lookup collections: %s", egg_error_message (error));
		g_clear_error (&error);
		return;
	}

	for (l = collections; l; l = g_list_next (l)) {

		identifier = gck_object_get_data (l->data, CKA_ID, NULL, &n_identifier, &error);
		if (identifier == NULL) {
			g_warning ("couldn't get collection identifier: %s", egg_error_message (error));
			g_clear_error (&error);
			continue;
		}

		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
		g_free (identifier);

		(callback) (self, path, l->data, user_data);
		g_free (path);
	}

	gck_list_unref_free (collections);
}
Esempio n. 5
0
gboolean
gkd_secret_lock_all (GckSession *session,
                     DBusError *derr)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GError *error = NULL;
	GList *objects, *l;

	/* Lock all the main collections */
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_CREDENTIAL);
	gck_builder_add_boolean (&builder, CKA_GNOME_TRANSIENT, TRUE);

	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);
	if (error != NULL) {
		g_warning ("couldn't search for credential objects: %s", egg_error_message (error));
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't lock service");
		g_clear_error (&error);
		return FALSE;
	}

	for (l = objects; l; l = g_list_next (l)) {
		if (!gck_object_destroy (l->data, NULL, &error)) {
			g_warning ("couldn't destroy credential object: %s", egg_error_message (error));
			g_clear_error (&error);
		}
	}

	/* Now delete all session objects */
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
	gck_builder_add_string (&builder, CKA_G_COLLECTION, "session");

	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);
	if (error != NULL) {
		g_warning ("couldn't search for session items: %s", egg_error_message (error));
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't lock service");
		g_clear_error (&error);
		return FALSE;
	}

	for (l = objects; l; l = g_list_next (l)) {
		if (!gck_object_destroy (l->data, NULL, &error)) {
			g_warning ("couldn't destroy session item: %s", egg_error_message (error));
			g_clear_error (&error);
		}
	}

	gck_list_unref_free (objects);
	return TRUE;
}
static gboolean
unlock_or_create_login (GP11Module *module, const gchar *master)
{
	GError *error = NULL;
	GP11Session *session;
	GP11Object *login;
	GP11Object *cred;

	g_return_val_if_fail (GP11_IS_MODULE (module), FALSE);
	g_return_val_if_fail (master, FALSE);

	/* Find the login object */
	session = lookup_login_session (module);
	login = lookup_login_keyring (session);

	/* Create credentials for login object */
	cred = create_credential (session, login, master, &error);

	/* Failure, bad password? */
	if (cred == NULL) {
		if (login && g_error_matches (error, GP11_ERROR, CKR_PIN_INCORRECT))
			gkm_wrap_layer_hint_login_unlock_failure ();
		else
			g_warning ("couldn't create login credential: %s", egg_error_message (error));
		g_clear_error (&error);

	/* Non login keyring, create it */
	} else if (!login) {
		login = create_login_keyring (session, cred, &error);
		if (login == NULL && error) {
			g_warning ("couldn't create login keyring: %s", egg_error_message (error));
			g_clear_error (&error);
		}

	/* The unlock succeeded yay */
	} else {
		gkm_wrap_layer_hint_login_unlock_success ();
	}

	if (cred)
		g_object_unref (cred);
	if (login)
		g_object_unref (login);
	if (session)
		g_object_unref (session);

	return cred && login;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
static GckSlot*
calculate_secrets_slot (void)
{
	GckSlot *slot = NULL;
	GckModule *module;
	GList *modules;
	GError *err = NULL;
	CK_FUNCTION_LIST_PTR funcs;

	/* TODO: Should we be handling just one module here? */
	funcs = gkd_pkcs11_get_functions ();
	g_return_val_if_fail (funcs != NULL, NULL);

	module = gck_module_new (funcs);
	g_return_val_if_fail (module, NULL);

	modules = g_list_prepend (NULL, module);
	slot = gck_modules_token_for_uri (modules, "pkcs11:token=Secret%20Store", &err);
	if (!slot && err) {
		g_warning ("couldn't find secret store: %s", egg_error_message (err));
		g_clear_error (&err);
	}

	gck_list_unref_free (modules);
	return slot;
}
static GP11Object*
lookup_login_keyring (GP11Session *session)
{
	GError *error = NULL;
	GP11Object *login = NULL;
	GList *objects;
	guint length;

	g_return_val_if_fail (GP11_IS_SESSION (session), NULL);

	objects = gp11_session_find_objects (session, &error,
	                                     CKA_CLASS, GP11_ULONG, CKO_G_COLLECTION,
	                                     CKA_TOKEN, GP11_BOOLEAN, TRUE,
	                                     CKA_ID, (gsize)5, "login",
	                                     GP11_INVALID);

	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);
		gp11_object_set_session (login, session);
	} else if (length > 1) {
		g_warning ("more than one login keyring exists");
	}

	gp11_list_unref_free (objects);
	return login;
}
Esempio n. 10
0
static void
item_cleanup_search_results (GckSession *session, GList *items,
			     GList **locked, GList **unlocked)
{
	GError *error = NULL;
	gpointer value;
	gsize n_value;
	GList *l;

	*locked = NULL;
	*unlocked = NULL;

	for (l = items; l; l = g_list_next (l)) {
		value = gck_object_get_data (l->data, CKA_G_LOCKED, NULL, &n_value, &error);
		if (value == NULL) {
			if (!g_error_matches (error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID))
				g_warning ("couldn't check if item is locked: %s", egg_error_message (error));
			g_clear_error (&error);

		/* Is not locked */
		} if (n_value == 1 && *((CK_BBOOL*)value) == CK_FALSE) {
			*unlocked = g_list_prepend (*unlocked, l->data);

		/* Is locked */
		} else {
			*locked = g_list_prepend (*locked, l->data);
		}

		g_free (value);
	}

	*locked = g_list_reverse (*locked);
	*unlocked = g_list_reverse (*unlocked);
}
static gboolean
init_pin_for_uninitialized_slots (GP11Module *module, const gchar *master)
{
	GError *error = NULL;
	GList *slots, *l;
	gboolean initialize;
	GP11TokenInfo *info;
	GP11Session *session;

	g_return_val_if_fail (GP11_IS_MODULE (module), FALSE);
	g_return_val_if_fail (master, FALSE);

	slots = gp11_module_get_slots (module, TRUE);
	for (l = slots; l; l = g_list_next (l)) {
		info = gp11_slot_get_token_info (l->data);
		initialize = (info && !(info->flags & CKF_USER_PIN_INITIALIZED));

		if (initialize) {
			session = open_and_login_session (l->data, CKU_SO, NULL);
			if (session != NULL) {
				if (!gp11_session_init_pin (session, (const guchar*)master, strlen (master), &error)) {
					if (!g_error_matches (error, GP11_ERROR, CKR_FUNCTION_NOT_SUPPORTED))
						g_warning ("couldn't initialize slot with master password: %s",
						           egg_error_message (error));
					g_clear_error (&error);
				}
				g_object_unref (session);
			}
		}

		gp11_token_info_free (info);
	}
	gp11_list_unref_free (slots);
	return TRUE;
}
Esempio n. 12
0
int
main(int argc, char* argv[])
{
	GError *err = NULL;
	GOptionContext *context;

	context = g_option_context_new ("trust-file");
	g_option_context_add_main_entries (context, option_entries, GETTEXT_PACKAGE);
	if (!g_option_context_parse (context, &argc, &argv, &err))
		barf_and_die (egg_error_message (err), NULL);

	g_option_context_free (context);

	if (argc != 2)
		barf_and_die ("specify trust-file", NULL);

	if (((create_for_file ? 1 : 0) +
	     (refer_for_file ? 1 : 0) +
	     (add_trust_purpose ? 1 : 0)) > 1)
		barf_and_die ("incompatible options specified", NULL);

	if (create_for_file)
		create_trust_file_for_certificate (argv[1], create_for_file);
	else if (refer_for_file)
		create_trust_file_for_issuer_and_serial (argv[1], refer_for_file);
	else if (add_trust_purpose)
		add_trust_purpose_to_file (argv[1], add_trust_purpose);

	g_free (create_for_file);
	g_free (refer_for_file);
	g_free (add_trust_purpose);

	return 0;
}
DBusMessage*
gkd_dbus_introspect_handle (DBusMessage *message, const gchar *type)
{
	GError *error = NULL;
	DBusMessage *reply;
	gchar *filename;
	gchar *data;

	g_return_val_if_fail (message, NULL);
	g_return_val_if_fail (type, NULL);

	if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect") &&
	    dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID)) {

		filename = g_strconcat (INTROSPECTDIR, G_DIR_SEPARATOR_S, "introspect-", type, ".xml", NULL);
		g_file_get_contents (filename, &data, NULL, &error);
		g_free (filename);

		if (error != NULL) {
			g_warning ("couldn't load introspect data file: %s: %s",
			           filename, egg_error_message (error));
			g_clear_error (&error);
			return NULL;
		}

		reply = dbus_message_new_method_return (message);
		if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, &data, DBUS_TYPE_INVALID))
			g_return_val_if_reached (NULL);
		g_free (data);
		return reply;
	}

	return NULL;
}
Esempio n. 14
0
/**
* builder: The gtk builder to add the gku-prompt.ui to
*
* Create and set up the dialog
*
* Returns the new dialog
**/
static GtkDialog*
prepare_dialog (GtkBuilder *builder)
{
	GError *error = NULL;
	GtkDialog *dialog;

	if (!gtk_builder_add_from_file (builder, UIDIR "gku-prompt.ui", &error)) {
		g_warning ("couldn't load prompt ui file: %s", egg_error_message (error));
		g_clear_error (&error);
		return NULL;
	}

	dialog = GTK_DIALOG (gtk_builder_get_object (builder, "prompt_dialog"));
	g_return_val_if_fail (GTK_IS_DIALOG (dialog), NULL);

	prepare_visibility (builder, dialog);
	prepare_titlebar (builder, dialog);
	prepare_prompt (builder, dialog);
	prepare_buttons (builder, dialog);
	prepare_passwords (builder, dialog);
	prepare_security (builder, dialog);
	prepare_lock (builder, dialog);
	prepare_details (builder, dialog);

	return dialog;
}
Esempio n. 15
0
static gchar *
object_path_for_item (const gchar *base,
		      GckObject *item)
{
	GError *error = NULL;
	gpointer identifier;
	gsize n_identifier;
	gchar *alloc = NULL;
	gchar *path = NULL;

	if (base == NULL)
		base = alloc = collection_path_for_item (item);

	identifier = gck_object_get_data (item, CKA_ID, NULL, &n_identifier, &error);
	if (identifier == NULL) {
		g_warning ("couldn't get item identifier: %s", egg_error_message (error));
		g_clear_error (&error);
		path = NULL;

	} else {
		path = gkd_secret_util_build_path (base, identifier, n_identifier);
		g_free (identifier);
	}

	g_free (alloc);
	return path;
}
Esempio n. 16
0
static void
data_file_entry_added (GkmMate2File *store, const gchar *identifier, GkmMate2Storage *self)
{
    GError *error = NULL;
    GkmObject *object;
    gboolean ret;
    guchar *data;
    gsize n_data;
    GType type;
    gchar *path;

    g_return_if_fail (GKM_IS_MATE2_STORAGE (self));
    g_return_if_fail (identifier);

    /* Already have this object? */
    object = g_hash_table_lookup (self->identifier_to_object, identifier);
    if (object != NULL)
        return;

    /* Figure out what type of object we're dealing with */
    type = type_from_identifier (identifier);
    if (type == 0) {
        g_warning ("don't know how to load file in user store: %s", identifier);
        return;
    }

    /* Read the file in */
    path = g_build_filename (self->directory, identifier, NULL);
    ret = g_file_get_contents (path, (gchar**)&data, &n_data, &error);
    g_free (path);

    if (ret == FALSE) {
        g_warning ("couldn't read file in user store: %s: %s", identifier,
                   egg_error_message (error));
        g_clear_error (&error);
        return;
    }

    /* Make sure that the object wasn't tampered with */
    if (!check_object_hash (self, identifier, data, n_data)) {
        g_message ("file in user store doesn't match hash: %s", identifier);
        return;
    }

    /* Create a new object for this identifier */
    object = g_object_new (type, "unique", identifier, "module", self->module,
                           "manager", gkm_module_get_manager (self->module), NULL);
    g_return_if_fail (GKM_IS_SERIALIZABLE (object));
    g_return_if_fail (GKM_SERIALIZABLE_GET_INTERFACE (object)->extension);

    /* And load the data into it */
    if (gkm_serializable_load (GKM_SERIALIZABLE (object), self->login, data, n_data))
        take_object_ownership (self, identifier, object);
    else
        g_message ("failed to load file in user store: %s", identifier);

    g_free (data);
    g_object_unref (object);
}
Esempio n. 17
0
static gpointer
run_client_thread (gpointer data)
{
	gint *socket = data;
	GError *error = NULL;
	GkdGpgAgentCall call;
	GIOStatus status;
	gboolean cont = TRUE;
	gchar *line;
	gsize n_line;

	g_assert (GCK_IS_MODULE (pkcs11_module));

	call.sock = g_atomic_int_get (socket);
	call.channel = g_io_channel_unix_new (call.sock);
	g_io_channel_set_encoding (call.channel, NULL, NULL);
	g_io_channel_set_close_on_unref (call.channel, FALSE);
	call.module = g_object_ref (pkcs11_module);

	/* Initial response on the connection */
	gkd_gpg_agent_send_reply (&call, TRUE, "your orders please");

	while (cont) {
		line = NULL;
		n_line = 0;

		/* Read in a line */
		status = g_io_channel_read_line (call.channel, &line, &n_line, NULL, &error);
		switch (status) {
		case G_IO_STATUS_ERROR:
			g_critical ("gpg agent couldn't read from socket: %s",
			            egg_error_message (error));
			g_clear_error (&error);
			cont = FALSE;
			break;
		case G_IO_STATUS_NORMAL:
			cont = process_line (&call, line);
			g_free (line);
			break;
		case G_IO_STATUS_EOF:
			cont = FALSE;
			break;
		case G_IO_STATUS_AGAIN:
			break;
		default:
			g_return_val_if_reached (NULL);
			break;
		};
	}

	g_io_channel_shutdown (call.channel, FALSE, NULL);
	g_object_unref (call.module);

	close (call.sock);
	g_atomic_int_set (socket, -1);

	return NULL;
}
GP11Session*
gkd_secret_service_get_pkcs11_session (GkdSecretService *self, const gchar *caller)
{
	ServiceClient *client;
	GError *error = NULL;
	GP11TokenInfo *info;
	GP11Slot *slot;
	gulong flags;
	gboolean login;

	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
	g_return_val_if_fail (caller, NULL);

	client = g_hash_table_lookup (self->clients, caller);
	g_return_val_if_fail (client, NULL);

	/* Open a new session if necessary */
	if (!client->pkcs11_session) {
		flags = CKF_RW_SESSION | CKF_G_APPLICATION_SESSION;
		slot = gkd_secret_service_get_pkcs11_slot (self);
		client->pkcs11_session = gp11_slot_open_session_full (slot, flags, &client->app,
		                                                      NULL, NULL, &error);
		if (!client->pkcs11_session) {
			g_warning ("couldn't open pkcs11 session for secret service: %s",
			           egg_error_message (error));
			g_clear_error (&error);
			return NULL;
		}

		/* Perform the necessary 'user' login to secrets token. Doesn't unlock anything */
		info = gp11_slot_get_token_info (slot);
		login = info && (info->flags & CKF_LOGIN_REQUIRED);
		gp11_token_info_free (info);
		if (login && !gp11_session_login (client->pkcs11_session, CKU_USER, NULL, 0, &error)) {
			g_warning ("couldn't log in to pkcs11 session for secret service: %s",
			           egg_error_message (error));
			g_clear_error (&error);
			g_object_unref (client->pkcs11_session);
			client->pkcs11_session = NULL;
			return NULL;
		}
	}

	return client->pkcs11_session;
}
Esempio n. 19
0
static GckObject *
secret_objects_lookup_gck_object_for_path (GkdSecretObjects *self,
					   const gchar *sender,
					   const gchar *path,
					   GError **error_out)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GList *objects;
	GckSession *session;
	gchar *c_ident;
	gchar *i_ident;
	GckObject *object = NULL;
	GError *error = NULL;

	g_return_val_if_fail (path, FALSE);

	if (!gkd_secret_util_parse_path (path, &c_ident, &i_ident) || !c_ident)
		goto out;

	/* The session we're using to access the object */
	session = gkd_secret_service_get_pkcs11_session (self->service, sender);
	g_return_val_if_fail (session, FALSE);

	if (i_ident) {
		gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
		gck_builder_add_string (&builder, CKA_G_COLLECTION, c_ident);
		gck_builder_add_string (&builder, CKA_ID, i_ident);
	} else {
		gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION);
		gck_builder_add_string (&builder, CKA_ID, c_ident);
	}

	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);

	g_free (c_ident);
	g_free (i_ident);

	if (error != NULL) {
		g_warning ("couldn't lookup object: %s: %s", path, egg_error_message (error));
		g_clear_error (&error);
	}

	if (!objects)
		goto out;

	object = g_object_ref (objects->data);
	gck_list_unref_free (objects);

 out:
	if (!object)
		g_set_error (error_out, GKD_SECRET_ERROR,
			     GKD_SECRET_ERROR_NO_SUCH_OBJECT,
			     "The '%s' object does not exist",
			     path);

	return object;
}
int
main(int argc, char *argv[])
{
	GckModule *module;
	GError *error = NULL;
	GIOChannel *channel;
	GMainLoop *loop;
	gboolean ret;
	int sock;

	g_type_init ();

	if (!g_thread_supported ())
		g_thread_init (NULL);

	if (argc <= 1) {
		g_message ("specify pkcs11 module on the command line");
		return 1;
	}

	module = gck_module_initialize (argv[1], argc > 2 ? argv[2] : NULL, 0, &error);
	if (!module) {
		g_message ("couldn't load pkcs11 module: %s", egg_error_message (error));
		g_clear_error (&error);
		return 1;
	}


	g_signal_connect (module, "authenticate-slot", G_CALLBACK (authenticate_slot), NULL);
	g_signal_connect (module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);

	ret = gkd_ssh_agent_initialize_with_module (module);
	g_object_unref (module);

	if (ret == FALSE)
		return 1;

	sock = gkd_ssh_agent_startup ("/tmp");
	if (sock == -1)
		return 1;

	channel = g_io_channel_unix_new (sock);
	g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_client, NULL);
	g_io_channel_unref (channel);

	g_print ("SSH_AUTH_SOCK=%s\n", g_getenv ("SSH_AUTH_SOCK"));

	/* Run a main loop */
	loop = g_main_loop_new (NULL, FALSE);
	g_main_loop_run (loop);
	g_main_loop_unref (loop);

	gkd_ssh_agent_shutdown ();
	gkd_ssh_agent_uninitialize ();

	return 0;
}
Esempio n. 21
0
static void
create_trust_file_for_certificate (const gchar *filename, const gchar *certificate)
{
	GError *err = NULL;
	GNode *asn, *cert, *choice, *ref;
	GBytes *bytes, *result;
	gchar *data;
	gsize n_data;

	if (!g_file_get_contents (certificate, &data, &n_data, &err))
		barf_and_die ("couldn't read certificate file", egg_error_message (err));

	/* Make sure the certificate is */
	cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
	g_return_if_fail (cert);

	bytes = g_bytes_new_take (data, n_data);
	if (!egg_asn1x_decode (cert, bytes))
		barf_and_die ("couldn't parse der certificate file", egg_asn1x_message (cert));

	asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
	g_return_if_fail (asn);

	ref = egg_asn1x_node (asn, "reference", NULL);
	choice = egg_asn1x_node (ref, "certComplete", NULL);

	if (!egg_asn1x_set_choice (ref, choice) || !egg_asn1x_set_any_raw (choice, bytes))
		g_return_if_reached ();

	g_bytes_unref (bytes);

	result = egg_asn1x_encode (asn, NULL);
	if (result == NULL)
		barf_and_die ("couldn't encode the trust file", egg_asn1x_message (asn));

	egg_asn1x_destroy (asn);
	egg_asn1x_destroy (cert);

	if (!g_file_set_contents (filename, g_bytes_get_data (result, NULL),
	                          g_bytes_get_size (result), &err))
		barf_and_die ("couldn't write trust file", egg_error_message (err));

	g_bytes_unref (result);
}
Esempio n. 22
0
static void
add_trust_purpose_to_file (const gchar *filename, const gchar *purpose)
{
	GError *err = NULL;
	gchar *data;
	GBytes *result;
	gsize n_data;
	GNode *asn, *assertion;
	GBytes *bytes;

	if (!g_file_get_contents (filename, &data, &n_data, &err))
		barf_and_die ("couldn't read trust file", egg_error_message (err));

	/* Create up the trust structure */
	asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
	g_return_if_fail (asn);

	/* And parse it */
	bytes = g_bytes_new_take (data, n_data);
	if (!egg_asn1x_decode (asn, bytes))
		barf_and_die ("couldn't parse trust file", egg_asn1x_message (asn));
	g_bytes_unref (bytes);

	assertion = egg_asn1x_append (egg_asn1x_node (asn, "assertions", NULL));
	g_return_if_fail (assertion);

	if (!egg_asn1x_set_string_as_utf8 (egg_asn1x_node (assertion, "purpose", NULL), g_strdup (purpose), g_free))
		g_return_if_reached ();
	egg_asn1x_set_enumerated (egg_asn1x_node (assertion, "level", NULL), g_quark_from_string ("trusted"));

	result = egg_asn1x_encode (asn, NULL);
	if (result == NULL)
		barf_and_die ("couldn't encode trust file", egg_asn1x_message (asn));

	egg_asn1x_destroy (asn);

	if (!g_file_set_contents (filename, g_bytes_get_data (result, NULL),
	                          g_bytes_get_size (result), &err))
		barf_and_die ("couldn't write trust file", egg_error_message (err));

	g_bytes_unref (result);
}
Esempio n. 23
0
static void
store_default (GkdSecretService *self)
{
	GError *error = NULL;
	const gchar *identifier;

	identifier = g_hash_table_lookup (self->aliases, "default");
	if (!identifier)
		return;

	if (!g_file_set_contents (self->default_path, identifier, -1, &error))
		g_message ("couldn't store default keyring: %s", egg_error_message (error));
}
GckSession*
gkd_secret_service_get_pkcs11_session (GkdSecretService *self, const gchar *caller)
{
	ServiceClient *client;
	GError *error = NULL;
	GckSlot *slot;

	g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
	g_return_val_if_fail (caller, NULL);

	client = g_hash_table_lookup (self->clients, caller);
	g_return_val_if_fail (client, NULL);

	/* Open a new session if necessary */
	if (!client->pkcs11_session) {
		slot = gkd_secret_service_get_pkcs11_slot (self);
		client->pkcs11_session = gck_slot_open_session_full (slot, GCK_SESSION_READ_WRITE,
								     CKF_G_APPLICATION_SESSION, &client->app,
								     NULL, NULL, &error);
		if (!client->pkcs11_session) {
			g_warning ("couldn't open pkcs11 session for secret service: %s",
				   egg_error_message (error));
			g_clear_error (&error);
			return NULL;
		}

		if (!log_into_pkcs11_session (client->pkcs11_session, &error)) {
			g_warning ("couldn't log in to pkcs11 session for secret service: %s",
				   egg_error_message (error));
			g_clear_error (&error);
			g_object_unref (client->pkcs11_session);
			client->pkcs11_session = NULL;
			return NULL;
		}
	}

	return client->pkcs11_session;
}
Esempio n. 25
0
static GckSession*
lookup_login_session (GList *modules)
{
	GckSlot *slot = NULL;
	GError *error = NULL;
	GckSession *session;

	slot = gck_modules_token_for_uri (modules, "pkcs11:token=Secret%20Store", &error);
	if (!slot) {
		g_warning ("couldn't find secret store module: %s", egg_error_message (error));
		return NULL;
	}

	session = open_and_login_session (slot, CKU_USER, &error);
	if (error) {
		g_warning ("couldn't open pkcs11 session for login: %s", egg_error_message (error));
		g_clear_error (&error);
	}

	g_object_unref (slot);

	return session;
}
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);
}
Esempio n. 27
0
static gboolean
item_method_delete (GkdExportedItem *skeleton,
		    GDBusMethodInvocation *invocation,
		    GkdSecretObjects *self)
{
	GError *error = NULL;
	gchar *collection_path;
	gchar *item_path;
	GckObject *collection;
	GckObject *object;

	object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
	if (!object) {
		return TRUE;
	}

	collection_path = collection_path_for_item (object);
	item_path = object_path_for_item (NULL, object);

	if (gck_object_destroy (object, NULL, &error)) {
		collection = gkd_secret_objects_lookup_collection (self, NULL, collection_path);
		if (collection != NULL) {
			gkd_secret_objects_emit_item_deleted (self, collection, item_path);
			g_object_unref (collection);
		}

		/* No prompt necessary */
		gkd_exported_item_complete_delete (skeleton, invocation, "/");

	} else {
		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 delete a locked item");
		else
			g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_FAILED,
							       "Couldn't delete collection: %s",
							       egg_error_message (error));

		g_clear_error (&error);
	}

	g_free (collection_path);
	g_free (item_path);
	g_object_unref (object);

	return TRUE;
}
Esempio n. 28
0
static gboolean
object_property_set (GkdSecretObjects *objects,
		     GckObject *object,
		     const gchar *prop_name,
		     GVariant *value,
		     GError **error_out)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GError *error = NULL;
	gulong attr_type;

	/* What type of property is it? */
	if (!gkd_secret_property_get_type (prop_name, &attr_type)) {
		g_set_error (error_out, G_DBUS_ERROR,
			     G_DBUS_ERROR_UNKNOWN_PROPERTY,
			     "Object does not have the '%s' property",
			     prop_name);
		return FALSE;
	}

	/* Retrieve the actual attribute value */
	if (!gkd_secret_property_parse_variant (value, prop_name, &builder)) {
		gck_builder_clear (&builder);
		g_set_error (error_out, G_DBUS_ERROR,
			     G_DBUS_ERROR_INVALID_ARGS,
			     "The property type or value was invalid: %s",
			     prop_name);
		return FALSE;
	}

	gck_object_set (object, gck_builder_end (&builder), NULL, &error);

	if (error != NULL) {
		if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
			g_set_error (error_out, GKD_SECRET_ERROR,
				     GKD_SECRET_ERROR_IS_LOCKED,
				     "Cannot set property on a locked object");
		else
			g_set_error (error_out, G_DBUS_ERROR,
				     G_DBUS_ERROR_FAILED,
				     "Couldn't set '%s' property: %s",
				     prop_name, egg_error_message (error));
		g_clear_error (&error);
		return FALSE;
	}

	return TRUE;
}
Esempio n. 29
0
static GcrPrompt *
open_password_prompt (GckSession *session,
                      const gchar *keyid,
                      const gchar *errmsg,
                      const gchar *prompt_text,
                      const gchar *description,
                      gboolean confirm)
{
	GcrPrompt *prompt;
	GError *error = NULL;
	gboolean auto_unlock;
	const gchar *choice;

	g_assert (GCK_IS_SESSION (session));

	prompt = GCR_PROMPT (gcr_system_prompt_open (-1, NULL, &error));
	if (prompt == NULL) {
		g_warning ("couldn't create prompt for gnupg passphrase: %s", egg_error_message (error));
		g_error_free (error);
		return NULL;
	}

	gcr_prompt_set_title (prompt, _("Enter Passphrase"));
	gcr_prompt_set_message (prompt, prompt_text ? prompt_text : _("Enter Passphrase"));
	gcr_prompt_set_description (prompt, description);

	gcr_prompt_set_password_new (prompt, confirm);
	gcr_prompt_set_continue_label (prompt, _("Unlock"));

	if (errmsg)
		gcr_prompt_set_warning (prompt, errmsg);

	if (keyid == NULL) {
		gcr_prompt_set_choice_label (prompt, NULL);

	} else {
		auto_unlock = gkd_login_available (session);

		choice = NULL;
		if (auto_unlock)
			choice = _("Automatically unlock this key, whenever I'm logged in");
		gcr_prompt_set_choice_label (prompt, choice);

		load_unlock_options (prompt);
	}

	return prompt;
}
Esempio n. 30
0
gboolean
gkd_ssh_agent_initialize_with_module (GckModule *module)
{
	GckSession *session = NULL;
	GList *slots, *l;
	GArray *mechs;
	GError *error = NULL;

	g_assert (GCK_IS_MODULE (module));

	/* Find a good slot for our session keys */
	slots = gck_module_get_slots (module, TRUE);
	for (l = slots; session == NULL && l; l = g_list_next (l)) {

		/* Check that it has the mechanisms we need */
		mechs = gck_slot_get_mechanisms (l->data);
		if (gck_mechanisms_check (mechs, CKM_RSA_PKCS, CKM_DSA, GCK_INVALID)) {

			/* Try and open a session */
			session = gck_slot_open_session (l->data, GCK_SESSION_AUTHENTICATE, NULL, &error);
			if (!session) {
				g_warning ("couldn't create pkcs#11 session: %s", egg_error_message (error));
				g_clear_error (&error);
			}
		}

		g_array_unref (mechs);
	}

	gck_list_unref_free (slots);

	if (!session) {
		g_warning ("couldn't select a usable pkcs#11 slot for the ssh agent to use");
		return FALSE;
	}

	g_assert (!pkcs11_modules);
	pkcs11_modules = g_list_append (NULL, g_object_ref (module));

	pkcs11_main_mutex = g_new0 (GMutex, 1);
	g_mutex_init (pkcs11_main_mutex);
	pkcs11_main_cond = g_new0 (GCond, 1);
	g_cond_init (pkcs11_main_cond);
	pkcs11_main_checked = FALSE;
	pkcs11_main_session = session;

	return TRUE;
}