mirror of
https://github.com/morgan9e/grd
synced 2026-04-14 00:14:18 +09:00
.
This commit is contained in:
252
grd-credentials-libsecret.c
Normal file
252
grd-credentials-libsecret.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user