mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-06-08 16:00:18 +00:00
Add optional keyring + encrypted password fallback
This commit is contained in:
173
src/common/secretstore.c
Normal file
173
src/common/secretstore.c
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "zoitechat.h"
|
||||
#include "cfgfiles.h"
|
||||
#include "secretstore.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <wincred.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBSECRET
|
||||
#include <libsecret/secret.h>
|
||||
#endif
|
||||
|
||||
static char *secretstore_target (const char *network_name)
|
||||
{
|
||||
return g_strdup_printf ("zoitechat/network/%s", network_name ? network_name : "default");
|
||||
}
|
||||
|
||||
int secretstore_is_keyring_available (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return TRUE;
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
char *secretstore_get_network_password (const char *network_name)
|
||||
{
|
||||
char *target;
|
||||
target = secretstore_target (network_name);
|
||||
#ifdef WIN32
|
||||
{
|
||||
PCREDENTIALA cred = NULL;
|
||||
char *ret = NULL;
|
||||
if (CredReadA (target, CRED_TYPE_GENERIC, 0, &cred))
|
||||
{
|
||||
ret = g_strndup ((const char *) cred->CredentialBlob, cred->CredentialBlobSize);
|
||||
CredFree (cred);
|
||||
}
|
||||
g_free (target);
|
||||
return ret;
|
||||
}
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
char *ret = secret_password_lookup_sync (&schema, NULL, NULL, "network", target, NULL);
|
||||
g_free (target);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
g_free (target);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int secretstore_set_network_password (const char *network_name, const char *password)
|
||||
{
|
||||
char *target;
|
||||
target = secretstore_target (network_name);
|
||||
#ifdef WIN32
|
||||
{
|
||||
CREDENTIALA cred;
|
||||
memset (&cred, 0, sizeof (cred));
|
||||
cred.Type = CRED_TYPE_GENERIC;
|
||||
cred.TargetName = target;
|
||||
cred.CredentialBlobSize = (DWORD) strlen (password);
|
||||
cred.CredentialBlob = (LPBYTE) password;
|
||||
cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
|
||||
cred.UserName = "zoitechat";
|
||||
if (!CredWriteA (&cred, 0))
|
||||
{
|
||||
g_free (target);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (target);
|
||||
return TRUE;
|
||||
}
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
gboolean ok = secret_password_store_sync (&schema, SECRET_COLLECTION_DEFAULT,
|
||||
"ZoiteChat network password", password, NULL, NULL, "network", target, NULL);
|
||||
g_free (target);
|
||||
return ok;
|
||||
}
|
||||
#else
|
||||
g_free (target);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int secretstore_delete_network_password (const char *network_name)
|
||||
{
|
||||
char *target;
|
||||
target = secretstore_target (network_name);
|
||||
#ifdef WIN32
|
||||
{
|
||||
gboolean ok = CredDeleteA (target, CRED_TYPE_GENERIC, 0);
|
||||
g_free (target);
|
||||
return ok;
|
||||
}
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
gboolean ok = secret_password_clear_sync (&schema, NULL, NULL, "network", target, NULL);
|
||||
g_free (target);
|
||||
return ok;
|
||||
}
|
||||
#else
|
||||
g_free (target);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int secretstore_require_unlock (const char *network_name)
|
||||
{
|
||||
#ifdef WIN32
|
||||
return TRUE;
|
||||
#elif defined(HAVE_LIBSECRET)
|
||||
{
|
||||
static const SecretSchema schema = {
|
||||
"net.zoite.ZoiteChat.Network", SECRET_SCHEMA_NONE,
|
||||
{
|
||||
{ "network", SECRET_SCHEMA_ATTRIBUTE_STRING },
|
||||
{ NULL, 0 },
|
||||
}
|
||||
};
|
||||
char *target;
|
||||
char *password;
|
||||
GError *error = NULL;
|
||||
target = secretstore_target (network_name);
|
||||
password = secret_password_lookup_sync (&schema, NULL, &error, "network", target, NULL);
|
||||
g_free (target);
|
||||
if (password)
|
||||
{
|
||||
memset (password, 0, strlen (password));
|
||||
g_free (password);
|
||||
return TRUE;
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user