mirror of
https://github.com/morgan9e/grd
synced 2026-04-13 16:04:13 +09:00
253 lines
6.9 KiB
C
253 lines
6.9 KiB
C
/*
|
|
* Copyright (C) 2018-2022 Red Hat Inc.
|
|
* Copyright (C) 2020 Pascal Nowack
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
* 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "grd-credentials-libsecret.h"
|
|
|
|
#include <gio/gio.h>
|
|
#include <libsecret/secret.h>
|
|
#include <stdio.h>
|
|
|
|
#define GRD_RDP_CREDENTIALS_SCHEMA (get_rdp_schema ())
|
|
|
|
#define GRD_VNC_PASSWORD_SCHEMA (get_vnc_schema ())
|
|
#define GRD_VNC_LEGACY_PASSWORD_SCHEMA (get_legacy_vnc_schema ())
|
|
|
|
struct _GrdCredentialsLibsecret
|
|
{
|
|
GrdCredentials parent;
|
|
};
|
|
|
|
G_DEFINE_TYPE (GrdCredentialsLibsecret,
|
|
grd_credentials_libsecret,
|
|
GRD_TYPE_CREDENTIALS)
|
|
|
|
static const SecretSchema *
|
|
get_rdp_schema (void)
|
|
{
|
|
static const SecretSchema grd_rdp_credentials_schema = {
|
|
.name = "org.gnome.RemoteDesktop.RdpCredentials",
|
|
.flags = SECRET_SCHEMA_NONE,
|
|
.attributes = {
|
|
{ "credentials", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
{ "NULL", 0 },
|
|
},
|
|
};
|
|
|
|
return &grd_rdp_credentials_schema;
|
|
}
|
|
|
|
static const SecretSchema *
|
|
get_legacy_vnc_schema (void)
|
|
{
|
|
static const SecretSchema grd_vnc_password_schema = {
|
|
.name = "org.gnome.RemoteDesktop.VncPassword",
|
|
.flags = SECRET_SCHEMA_NONE,
|
|
.attributes = {
|
|
{ "password", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
{ "NULL", 0 },
|
|
},
|
|
};
|
|
|
|
return &grd_vnc_password_schema;
|
|
}
|
|
|
|
static const SecretSchema *
|
|
get_vnc_schema (void)
|
|
{
|
|
static const SecretSchema grd_vnc_password_schema = {
|
|
.name = "org.gnome.RemoteDesktop.VncCredentials",
|
|
.flags = SECRET_SCHEMA_NONE,
|
|
.attributes = {
|
|
{ "password", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
{ "NULL", 0 },
|
|
},
|
|
};
|
|
|
|
return &grd_vnc_password_schema;
|
|
}
|
|
|
|
static const SecretSchema *
|
|
schema_from_type (GrdCredentialsType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case GRD_CREDENTIALS_TYPE_RDP:
|
|
return GRD_RDP_CREDENTIALS_SCHEMA;
|
|
case GRD_CREDENTIALS_TYPE_VNC:
|
|
return GRD_VNC_PASSWORD_SCHEMA;
|
|
}
|
|
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
static const char *
|
|
description_from_type (GrdCredentialsType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case GRD_CREDENTIALS_TYPE_RDP:
|
|
return "GNOME Remote Desktop RDP credentials";
|
|
case GRD_CREDENTIALS_TYPE_VNC:
|
|
return "GNOME Remote Desktop VNC password";
|
|
}
|
|
|
|
g_assert_not_reached ();
|
|
}
|
|
|
|
static gboolean
|
|
grd_credentials_libsecret_store (GrdCredentials *credentials,
|
|
GrdCredentialsType type,
|
|
GVariant *variant,
|
|
GError **error)
|
|
{
|
|
g_autofree char *serialized = NULL;
|
|
|
|
g_variant_ref_sink (variant);
|
|
serialized = g_variant_print (variant, TRUE);
|
|
g_variant_unref (variant);
|
|
|
|
return secret_password_store_sync (schema_from_type (type),
|
|
SECRET_COLLECTION_DEFAULT,
|
|
description_from_type (type),
|
|
serialized,
|
|
NULL, error,
|
|
NULL);
|
|
}
|
|
|
|
static GVariant *
|
|
grd_credentials_libsecret_lookup (GrdCredentials *credentials,
|
|
GrdCredentialsType type,
|
|
GError **error)
|
|
{
|
|
g_autofree char *serialized = NULL;
|
|
|
|
serialized = secret_password_lookup_sync (schema_from_type (type),
|
|
NULL, error,
|
|
NULL);
|
|
if (!serialized)
|
|
return NULL;
|
|
|
|
return g_variant_parse (NULL, serialized, NULL, NULL, error);
|
|
}
|
|
|
|
static gboolean
|
|
grd_credentials_libsecret_clear (GrdCredentials *credentials,
|
|
GrdCredentialsType type,
|
|
GError **error)
|
|
{
|
|
g_autoptr (GError) local_error = NULL;
|
|
|
|
secret_password_clear_sync (schema_from_type (type),
|
|
NULL, &local_error,
|
|
NULL);
|
|
if (local_error)
|
|
{
|
|
g_propagate_error (error, g_steal_pointer (&local_error));
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
GrdCredentialsLibsecret *
|
|
grd_credentials_libsecret_new (void)
|
|
{
|
|
return g_object_new (GRD_TYPE_CREDENTIALS_LIBSECRET, NULL);
|
|
}
|
|
|
|
static void
|
|
grd_credentials_libsecret_init (GrdCredentialsLibsecret *credentials_libsecret)
|
|
{
|
|
}
|
|
|
|
static void
|
|
maybe_migrate_legacy_vnc_password (GrdCredentials *credentials)
|
|
{
|
|
g_autoptr (GError) error = NULL;
|
|
g_autofree char *password = NULL;
|
|
|
|
password = secret_password_lookup_sync (GRD_VNC_LEGACY_PASSWORD_SCHEMA,
|
|
NULL, &error,
|
|
NULL);
|
|
if (!password)
|
|
{
|
|
if (error)
|
|
{
|
|
g_printerr ("Failed to lookup legacy VNC password schema: %s\n",
|
|
error->message);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_printerr ("Migrating VNC password to new schema... ");
|
|
|
|
if (!grd_credentials_store (credentials,
|
|
GRD_CREDENTIALS_TYPE_VNC,
|
|
g_variant_new_string (password),
|
|
&error))
|
|
{
|
|
g_printerr ("Failed to migrate VNC password to new schema: %s\n",
|
|
error->message);
|
|
}
|
|
else
|
|
{
|
|
if (!secret_password_clear_sync (GRD_VNC_LEGACY_PASSWORD_SCHEMA,
|
|
NULL, &error, NULL) &&
|
|
error)
|
|
{
|
|
g_printerr ("Failed to clear VNC password from old schema: %s\n",
|
|
error->message);
|
|
}
|
|
else
|
|
{
|
|
g_printerr ("OK\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
grd_credentials_libsecret_constructed (GObject *object)
|
|
{
|
|
GrdCredentials *credentials = GRD_CREDENTIALS (object);
|
|
|
|
maybe_migrate_legacy_vnc_password (credentials);
|
|
|
|
G_OBJECT_CLASS (grd_credentials_libsecret_parent_class)->constructed (object);
|
|
}
|
|
|
|
static void
|
|
grd_credentials_libsecret_class_init (GrdCredentialsLibsecretClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
GrdCredentialsClass *credentials_class = GRD_CREDENTIALS_CLASS (klass);
|
|
|
|
object_class->constructed = grd_credentials_libsecret_constructed;
|
|
|
|
credentials_class->store = grd_credentials_libsecret_store;
|
|
credentials_class->lookup = grd_credentials_libsecret_lookup;
|
|
credentials_class->clear = grd_credentials_libsecret_clear;
|
|
}
|