summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2025-02-10 00:39:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2025-02-10 00:39:50 (GMT)
commitd01509d9afe32c0d98d2efba5e75a9df53ac5de9 (patch)
treef4d742bec88c34ee9d04c42d16dc7ac84bc642b7 /plugins/pychrysalide
parent71d0b80eca2fd2aed5883e2a6a57cb8c03aa27ff (diff)
Switch the secure storage to the GObject system.
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r--plugins/pychrysalide/core/Makefile.am3
-rw-r--r--plugins/pychrysalide/core/module.c2
-rw-r--r--plugins/pychrysalide/glibext/Makefile.am1
-rw-r--r--plugins/pychrysalide/glibext/module.c2
-rw-r--r--plugins/pychrysalide/glibext/secstorage.c (renamed from plugins/pychrysalide/core/secstorage.c)483
-rw-r--r--plugins/pychrysalide/glibext/secstorage.h (renamed from plugins/pychrysalide/core/secstorage.h)18
-rw-r--r--plugins/pychrysalide/helpers.h2
7 files changed, 338 insertions, 173 deletions
diff --git a/plugins/pychrysalide/core/Makefile.am b/plugins/pychrysalide/core/Makefile.am
index 6ba9fc8..5588c9f 100644
--- a/plugins/pychrysalide/core/Makefile.am
+++ b/plugins/pychrysalide/core/Makefile.am
@@ -15,8 +15,7 @@ libpychrysacore_la_SOURCES = \
constants.h constants.c \
logs.h logs.c \
module.h module.c \
- nox.h nox.c \
- secstorage.h secstorage.c
+ nox.h nox.c
libpychrysacore_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
diff --git a/plugins/pychrysalide/core/module.c b/plugins/pychrysalide/core/module.c
index 7eceddd..4af0403 100644
--- a/plugins/pychrysalide/core/module.c
+++ b/plugins/pychrysalide/core/module.c
@@ -35,7 +35,6 @@
//#include "params.h"
//#include "processors.h"
//#include "queue.h"
-#include "secstorage.h"
#include "../helpers.h"
@@ -111,7 +110,6 @@ bool populate_core_module(void)
//if (result) result = populate_core_module_with_params();
//if (result) result = populate_core_module_with_processors();
//if (result) result = populate_core_module_with_queue();
- if (result) result = populate_core_module_with_secstorage();
assert(result);
diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index 2d45244..af1d9f2 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -26,6 +26,7 @@ libpychrysaglibext_la_SOURCES = \
module.h module.c \
objhole.h objhole.c \
portion.h portion.c \
+ secstorage.h secstorage.c \
singleton.h singleton.c \
strbuilder.h strbuilder.c \
work.h work.c \
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index 8adae07..6ce0709 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -43,6 +43,7 @@
#include "hashable.h"
#include "objhole.h"
#include "portion.h"
+#include "secstorage.h"
#include "singleton.h"
#include "strbuilder.h"
#include "work.h"
@@ -121,6 +122,7 @@ bool populate_glibext_module(void)
if (result) result = ensure_python_thick_object_is_registered();
if (result) result = ensure_python_binary_portion_is_registered();
if (result) result = ensure_python_generic_work_is_registered();
+ if (result) result = ensure_python_secret_storage_is_registered();
if (result) result = ensure_python_singleton_factory_is_registered();
if (result) result = ensure_python_work_queue_is_registered();
diff --git a/plugins/pychrysalide/core/secstorage.c b/plugins/pychrysalide/glibext/secstorage.c
index 67779af..b5adb7c 100644
--- a/plugins/pychrysalide/core/secstorage.c
+++ b/plugins/pychrysalide/glibext/secstorage.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * secstorage.c - équivalent Python du fichier "core/secstorage.c"
+ * secstorage.c - équivalent Python du fichier "glibext/secstorage.c"
*
* Copyright (C) 2025 Cyrille Bagard
*
@@ -25,7 +25,11 @@
#include "secstorage.h"
-#include <core/secstorage.h>
+#include <assert.h>
+#include <pygobject.h>
+
+
+#include <glibext/secstorage-int.h>
#include "../access.h"
@@ -34,76 +38,107 @@
-/* Détermine si une clef de chiffrement protégée est en place. */
-static PyObject *py_secstorage_has_secret_storage_key(PyObject *, PyObject *);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(secret_storage, G_TYPE_SECRET_STORAGE);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_secret_storage_init(PyObject *, PyObject *, PyObject *);
-/* Définit un mot de passe pour protéger une clef maître. */
-static PyObject *py_secstorage_set_secret_storage_password(PyObject *, PyObject *);
-/* Détermine si la clef de chiffrement maître est vérouillée. */
-static PyObject *py_secstorage_is_secret_storage_locked(PyObject *, PyObject *);
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Définit un mot de passe pour protéger une clef maître. */
+static PyObject *py_secret_storage_set_password(PyObject *, PyObject *);
/* Déverrouille la clef de chiffrement maître. */
-static PyObject *py_secstorage_unlock_secret_storage(PyObject *, PyObject *);
+static PyObject *py_secret_storage_unlock(PyObject *, PyObject *);
/* Verrouille la clef de chiffrement maître. */
-static PyObject *py_secstorage_lock_secret_storage(PyObject *, PyObject *);
+static PyObject *py_secret_storage_lock(PyObject *, PyObject *);
/* Chiffre des données avec la clef de chiffrement maître. */
-static PyObject *py_secstorage_encrypt_secret_storage_data(PyObject *, PyObject *);
+static PyObject *py_secret_storage_encrypt_data(PyObject *, PyObject *);
/* Déchiffre des données avec la clef de chiffrement maître. */
-static PyObject *py_secstorage_decrypt_secret_storage_data(PyObject *, PyObject *);
+static PyObject *py_secret_storage_decrypt_data(PyObject *, PyObject *);
+/* Détermine si une clef de chiffrement protégée est en place. */
+static PyObject *py_secret_storage_has_key(PyObject *, void *);
+
+/* Détermine si la clef de chiffrement maître est vérouillée. */
+static PyObject *py_secret_storage_is_locked(PyObject *, void *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : self = objet Python concerné par l'appel. *
+* Paramètres : self = objet à initialiser (théoriquement). *
* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Détermine si un mot de passe est actuellement en place. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Bilan de l'analyse. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_secstorage_has_secret_storage_key(PyObject *self, PyObject *args)
+static int py_secret_storage_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *result; /* Conversion à retourner */
GSettings *settings; /* Configuration à considérer */
int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de situation */
+ GSecretStorage *storage; /* Stockage natif à manipuler */
+
+#define SECRET_STORAGE_DOC \
+ "SecretStorage acts as guardian for secrets using ecryption," \
+ " mainly for sensitive information stored as configuration" \
+ " parameters.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " SecretStorage(settings)" \
+ "\n" \
+ "The *settings* arguement must point to a GSettings intance;" \
+ " the main configuration settings are used by default." \
-#define SECSTORAGE_HAS_SECRET_STORAGE_KEY_METHOD PYTHON_METHOD_DEF \
-( \
- has_secret_storage_key, "/, settings=None", \
- METH_VARARGS, py_secstorage, \
- "Indicate if a master key used for protecting secrets seems to have"\
- " been defined.\n" \
- "\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default.\n" \
- "\n" \
- "The result is a boolean status: *True* if the master key seems" \
- " to exist, *False* otherwise." \
-)
+ settings = NULL;
- ret = PyArg_ParseTuple(args, "O&", convert_to_gsettings, &settings);
- if (!ret) return NULL;
+ ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
+ if (!ret) return -1;
- status = has_secret_storage_key(settings);
+ /* Initialisation d'un objet GLib */
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- return result;
+ /* Eléments de base */
+
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ if (!g_secret_storage_create(storage, settings))
+ return -1;
+
+ return 0;
}
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = objet Python concerné par l'appel. *
@@ -117,85 +152,35 @@ static PyObject *py_secstorage_has_secret_storage_key(PyObject *self, PyObject *
* *
******************************************************************************/
-static PyObject *py_secstorage_set_secret_storage_password(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_set_password(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
const char *passwd; /* Mot de passe associé */
int ret; /* Bilan de lecture des args. */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
-#define SECSTORAGE_SET_SECRET_STORAGE_PASSWORD_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_SET_PASSWORD_METHOD PYTHON_METHOD_DEF \
( \
- set_secret_storage_password, "/, settings=None, password=''", \
- METH_VARARGS, py_secstorage, \
+ set_password, "/, password=''", \
+ METH_VARARGS, py_secret_storage, \
"Create a master key used for protecting secrets. This key is" \
" itself protected by the provided password.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default. The supplied" \
- " *password* has to be a string.\n" \
+ "The supplied *password* has to be a string.\n" \
"\n" \
"The result is a boolean status: *True* if the operation successed,"\
" *False* otherwise." \
)
- settings = NULL;
passwd = "";
- ret = PyArg_ParseTuple(args, "|O&s", convert_to_gsettings, &settings, &passwd);
+ ret = PyArg_ParseTuple(args, "|s", &passwd);
if (!ret) return NULL;
- status = set_secret_storage_password(settings, passwd);
-
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
-
- return result;
-
-}
+ storage = G_SECRET_STORAGE(pygobject_get(self));
-
-/******************************************************************************
-* *
-* Paramètres : self = objet Python concerné par l'appel. *
-* args = arguments fournis à l'appel. *
-* *
-* Description : Détermine si la clef de chiffrement maître est vérouillée. *
-* *
-* Retour : Bilan de la détermination. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_secstorage_is_secret_storage_locked(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
- int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de situation */
-
-#define SECSTORAGE_IS_SECRET_STORAGE_LOCKED_METHOD PYTHON_METHOD_DEF \
-( \
- is_secret_storage_locked, "/, settings=None", \
- METH_VARARGS, py_secstorage, \
- "Indicate if the master key used for protecting secrets is" \
- " currently decrypted in memory.\n" \
- "\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default.\n" \
- "\n" \
- "The result is a boolean status: *True* if the master key is" \
- " unlocked and ready for use, *False* otherwise." \
-)
-
- settings = NULL;
-
- ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
- if (!ret) return NULL;
-
- status = is_secret_storage_locked(settings);
+ status = g_secret_storage_set_password(storage, passwd);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -218,35 +203,35 @@ static PyObject *py_secstorage_is_secret_storage_locked(PyObject *self, PyObject
* *
******************************************************************************/
-static PyObject *py_secstorage_unlock_secret_storage(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_unlock(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
const char *passwd; /* Mot de passe associé */
int ret; /* Bilan de lecture des args. */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
-#define SECSTORAGE_UNLOCK_SECRET_STORAGE_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_UNLOCK_METHOD PYTHON_METHOD_DEF \
( \
- unlock_secret_storage, "/, settings=None, password=''", \
- METH_VARARGS, py_secstorage, \
+ unlock, "/, password=''", \
+ METH_VARARGS, py_secret_storage, \
"Decrypt in memory the master key used for protecting secrets.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default. The supplied" \
- " *password* is the primary password used to protect this key.\n" \
+ "The supplied *password* is the primary password used to protect" \
+ " this key.\n" \
"\n" \
"The result is a boolean status: *True* if the operation successed" \
" or if the master key is already unlocked, *False* otherwise." \
)
- settings = NULL;
passwd = "";
- ret = PyArg_ParseTuple(args, "|O&s", convert_to_gsettings, &settings, &passwd);
+ ret = PyArg_ParseTuple(args, "|s", &passwd);
if (!ret) return NULL;
- status = unlock_secret_storage(settings, passwd);
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_unlock(storage, passwd);
result = status ? Py_True : Py_False;
Py_INCREF(result);
@@ -269,28 +254,21 @@ static PyObject *py_secstorage_unlock_secret_storage(PyObject *self, PyObject *a
* *
******************************************************************************/
-static PyObject *py_secstorage_lock_secret_storage(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_lock(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
- GSettings *settings; /* Configuration à considérer */
- int ret; /* Bilan de lecture des args. */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
-#define SECSTORAGE_LOCK_SECRET_STORAGE_METHOD PYTHON_METHOD_DEF \
-( \
- lock_secret_storage, "/, settings=None", \
- METH_VARARGS, py_secstorage, \
- "Clear from memory the master key used for protecting secrets.\n" \
- "\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default." \
+#define SECRET_STORAGE_LOCK_METHOD PYTHON_METHOD_DEF \
+( \
+ lock, "", \
+ METH_NOARGS, py_secret_storage, \
+ "Clear from memory the master key used for protecting secrets." \
)
- settings = NULL;
+ storage = G_SECRET_STORAGE(pygobject_get(self));
- ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
- if (!ret) return NULL;
-
- lock_secret_storage(settings);
+ g_secret_storage_lock(storage);
result = Py_None;
Py_INCREF(result);
@@ -313,39 +291,38 @@ static PyObject *py_secstorage_lock_secret_storage(PyObject *self, PyObject *arg
* *
******************************************************************************/
-static PyObject *py_secstorage_encrypt_secret_storage_data(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_encrypt_data(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
const char *data_in; /* Données d'entrée à chiffrer */
Py_ssize_t size_in; /* Quantité de ces données */
- GSettings *settings; /* Configuration à considérer */
int ret; /* Bilan de lecture des args. */
sized_binary_t in; /* Données à chiffer */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
sized_binary_t out; /* Données chiffrées */
-#define SECSTORAGE_ENCRYPT_SECRET_STORAGE_DATA_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_ENCRYPT_DATA_METHOD PYTHON_METHOD_DEF \
( \
- encrypt_secret_storage_data, "data, /, settings=None", \
- METH_VARARGS, py_secstorage, \
+ encrypt_data, "data", \
+ METH_VARARGS, py_secret_storage, \
"Encrypt data using an unlocked the master key.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default." \
+ "The *data* arguement points to bytes to process." \
"\n" \
- "The result is either encrypted data as bytes in case of success," \
+ "The result is either encrypted *data* as bytes in case of success,"\
" or *None* in case of failure." \
)
- settings = NULL;
-
- ret = PyArg_ParseTuple(args, "s#|O&", &data_in, &size_in, convert_to_gsettings, &settings);
+ ret = PyArg_ParseTuple(args, "s#", &data_in, &size_in);
if (!ret) return NULL;
in.static_data = data_in;
in.size = size_in;
- status = encrypt_secret_storage_data(settings, &in, &out);
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_encrypt_data(storage, &in, &out);
if (status)
{
@@ -377,39 +354,38 @@ static PyObject *py_secstorage_encrypt_secret_storage_data(PyObject *self, PyObj
* *
******************************************************************************/
-static PyObject *py_secstorage_decrypt_secret_storage_data(PyObject *self, PyObject *args)
+static PyObject *py_secret_storage_decrypt_data(PyObject *self, PyObject *args)
{
PyObject *result; /* Conversion à retourner */
const char *data_in; /* Données d'entrée à chiffrer */
Py_ssize_t size_in; /* Quantité de ces données */
- GSettings *settings; /* Configuration à considérer */
int ret; /* Bilan de lecture des args. */
sized_binary_t in; /* Données à chiffer */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
bool status; /* Bilan de situation */
sized_binary_t out; /* Données chiffrées */
-#define SECSTORAGE_DECRYPT_SECRET_STORAGE_DATA_METHOD PYTHON_METHOD_DEF \
+#define SECRET_STORAGE_DECRYPT_DATA_METHOD PYTHON_METHOD_DEF \
( \
- decrypt_secret_storage_data, "data, /, settings=None", \
- METH_VARARGS, py_secstorage, \
+ decrypt_data, "data", \
+ METH_VARARGS, py_secret_storage, \
"Decrypt data using an unlocked the master key.\n" \
"\n" \
- "The *settings* arguement must point to a GSettings intance; the" \
- " main configuration settings are used by default." \
+ "The *data* arguement points to bytes to process." \
"\n" \
- "The result is either decrypted data as bytes in case of success," \
+ "The result is either decrypted *data* as bytes in case of success,"\
" or *None* in case of failure." \
)
- settings = NULL;
-
- ret = PyArg_ParseTuple(args, "s#|O&", &data_in, &size_in, convert_to_gsettings, &settings);
+ ret = PyArg_ParseTuple(args, "s#", &data_in, &size_in);
if (!ret) return NULL;
in.static_data = data_in;
in.size = size_in;
- status = decrypt_secret_storage_data(settings, &in, &out);
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_decrypt_data(storage, &in, &out);
if (status)
{
@@ -430,35 +406,218 @@ static PyObject *py_secstorage_decrypt_secret_storage_data(PyObject *self, PyObj
/******************************************************************************
* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Détermine si une clef de chiffrement protégée est en place. *
+* *
+* Retour : Bilan de l'analyse. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_secret_storage_has_key(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
+ bool status; /* Bilan de consultation */
+
+#define PY_SECRET_STORAGE_HAS_KEY_ATTRIB PYTHON_HAS_DEF_FULL \
+( \
+ key, py_secret_storage, \
+ "Indicate if a master key used for protecting secrets seems to have"\
+ " been defined. Without any unlocking attempt, the test only relies"\
+ " on the length of saved master data.\n" \
+ "\n" \
+ "The returned status is a boolean status: *True* if the master key" \
+ " seems to exist, *False* otherwise." \
+)
+
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_has_key(storage);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet Python concerné par l'appel. *
+* closure = non utilisé ici. *
+* *
+* Description : Détermine si la clef de chiffrement maître est vérouillée. *
+* *
+* Retour : Bilan de la détermination. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_secret_storage_is_locked(PyObject *self, void *closure)
+{
+ PyObject *result; /* Instance Python à retourner */
+ GSecretStorage *storage; /* Stockage sécurisé visé */
+ bool status; /* Bilan de consultation */
+
+#define SECRET_STORAGE_IS_LOCKED_ATTRIB PYTHON_IS_DEF_FULL \
+( \
+ locked, py_secret_storage, \
+ "Indicate if the master key used for protecting secrets is" \
+ " currently decrypted in memory.\n" \
+ "\n" \
+ "The *settings* arguement must point to a GSettings intance; the" \
+ " main configuration settings are used by default.\n" \
+ "\n" \
+ "The returned status is a boolean status: *True* if the master key" \
+ " is unlocked and ready for use, *False* otherwise." \
+)
+
+ storage = G_SECRET_STORAGE(pygobject_get(self));
+
+ status = g_secret_storage_is_locked(storage);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : - *
* *
-* Description : Définit une extension du module 'core' à compléter. *
+* Description : Fournit un accès à une définition de type à diffuser. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Définition d'objet pour Python. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool populate_core_module_with_secstorage(void)
+PyTypeObject *get_python_secret_storage_type(void)
{
- bool result; /* Bilan à retourner */
- PyObject *module; /* Module à recompléter */
+ static PyMethodDef py_secret_storage_methods[] = {
+ SECRET_STORAGE_SET_PASSWORD_METHOD,
+ SECRET_STORAGE_UNLOCK_METHOD,
+ SECRET_STORAGE_LOCK_METHOD,
+ SECRET_STORAGE_ENCRYPT_DATA_METHOD,
+ SECRET_STORAGE_DECRYPT_DATA_METHOD,
+ { NULL }
+ };
- static PyMethodDef py_secstorage_methods[] = {
- SECSTORAGE_HAS_SECRET_STORAGE_KEY_METHOD,
- SECSTORAGE_SET_SECRET_STORAGE_PASSWORD_METHOD,
- SECSTORAGE_IS_SECRET_STORAGE_LOCKED_METHOD,
- SECSTORAGE_UNLOCK_SECRET_STORAGE_METHOD,
- SECSTORAGE_LOCK_SECRET_STORAGE_METHOD,
- SECSTORAGE_ENCRYPT_SECRET_STORAGE_DATA_METHOD,
- SECSTORAGE_DECRYPT_SECRET_STORAGE_DATA_METHOD,
+ static PyGetSetDef py_secret_storage_getseters[] = {
+ PY_SECRET_STORAGE_HAS_KEY_ATTRIB,
+ SECRET_STORAGE_IS_LOCKED_ATTRIB,
{ NULL }
};
- module = get_access_to_python_module("pychrysalide.core");
+ static PyTypeObject py_secret_storage_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.SecretStorage",
+ .tp_basicsize = sizeof(PyGObject),
+
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+ .tp_doc = SECRET_STORAGE_DOC,
+
+ .tp_methods = py_secret_storage_methods,
+ .tp_getset = py_secret_storage_getseters,
+
+ .tp_init = py_secret_storage_init,
+ .tp_new = py_secret_storage_new,
+
+ };
+
+ return &py_secret_storage_type;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : module = module dont la définition est à compléter. *
+* *
+* Description : Prend en charge l'objet 'pychrysalide.glibext.SecretStorage'.*
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool ensure_python_secret_storage_is_registered(void)
+{
+ PyTypeObject *type; /* Type Python 'SecretStorage' */
+ PyObject *module; /* Module à recompléter */
+ PyObject *dict; /* Dictionnaire du module */
+
+ type = get_python_secret_storage_type();
- result = register_python_module_methods(module, py_secstorage_methods);
+ if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+ {
+ module = get_access_to_python_module("pychrysalide.glibext");
+
+ dict = PyModule_GetDict(module);
+
+ if (!register_class_for_pygobject(dict, G_TYPE_SECRET_STORAGE, type))
+ return false;
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : arg = argument quelconque à tenter de convertir. *
+* dst = destination des valeurs récupérées en cas de succès. *
+* *
+* Description : Tente de convertir en gardien des secrets avec stockage. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_secret_storage(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_secret_storage_type());
+
+ switch (result)
+ {
+ case -1:
+ /* L'exception est déjà fixée par Python */
+ result = 0;
+ break;
+
+ case 0:
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to secret storage");
+ break;
+
+ case 1:
+ *((GSecretStorage **)dst) = G_SECRET_STORAGE(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
return result;
diff --git a/plugins/pychrysalide/core/secstorage.h b/plugins/pychrysalide/glibext/secstorage.h
index d05d052..68726c3 100644
--- a/plugins/pychrysalide/core/secstorage.h
+++ b/plugins/pychrysalide/glibext/secstorage.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * secstorage.h - prototypes pour l'équivalent Python du fichier "core/secstorage.h"
+ * secstorage.h - prototypes pour l'équivalent Python du fichier "glibext/secstorage.h"
*
* Copyright (C) 2025 Cyrille Bagard
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_CORE_SECSTORAGE_H
-#define _PLUGINS_PYCHRYSALIDE_CORE_SECSTORAGE_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_SECSTORAGE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_SECSTORAGE_H
#include <Python.h>
@@ -31,9 +31,15 @@
-/* Définit une extension du module 'core' à compléter. */
-bool populate_core_module_with_secstorage(void);
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_secret_storage_type(void);
+/* Prend en charge l'objet 'pychrysalide.glibext.SecretStorage'. */
+bool ensure_python_secret_storage_is_registered(void);
+/* Tente de convertir en gardien des secrets avec stockage. */
+int convert_to_secret_storage(PyObject *, void *);
-#endif /* _PLUGINS_PYCHRYSALIDE_CORE_SECSTORAGE_H */
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_SECSTORAGE_H */
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 0aaf976..745d013 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -132,7 +132,7 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
PYTHON_GETSET_DEF("is_" #name, base ## _is_ ## name, NULL, ATTRIB_RO doc, NULL)
#define PYTHON_HAS_DEF_FULL(name, base, doc) \
- PYTHON_GETSET_DEF(#name, base ## _has_ ## name, NULL, ATTRIB_RO doc, NULL)
+ PYTHON_GETSET_DEF("has_" #name, base ## _has_ ## name, NULL, ATTRIB_RO doc, NULL)
#define PYTHON_RAWGET_DEF_FULL(name, base, doc) \
PYTHON_GETSET_DEF(#name, base ## _ ## name, NULL, ATTRIB_RO doc, NULL)