commit 904eb55d88ce675e414322c24cd67e1bff37182f
parent 2fe6e07cc51acfb3573b68da956dd54577859df2
Author: Jacki <jacki@thejackimonster.de>
Date: Sun, 18 Jan 2026 04:34:44 +0100
Implement transfer of secrets when renaming the current account
Signed-off-by: Jacki <jacki@thejackimonster.de>
Diffstat:
4 files changed, 143 insertions(+), 6 deletions(-)
diff --git a/src/event.c b/src/event.c
@@ -28,6 +28,7 @@
#include <gnunet/gnunet_chat_lib.h>
#include <gnunet/gnunet_common.h>
#include <stdio.h>
+#include <string.h>
#include "account.h"
#include "application.h"
@@ -465,7 +466,81 @@ _account_secret_lookup(MESSENGER_Application *app,
name = GNUNET_CHAT_account_get_name(account);
application_chat_unlock(app);
- secret_operation_generate(app, name, &_account_secret_lookup, account);
+ secret_operation_generate(
+ app,
+ name,
+ &_account_secret_lookup,
+ account
+ );
+ }
+}
+
+static void
+_account_secret_transferred(MESSENGER_Application *app,
+ const char *secret,
+ uint32_t secret_len,
+ gboolean success,
+ gboolean error,
+ gpointer user_data)
+{
+ g_assert(app);
+
+ char *names = user_data;
+
+ if (error)
+ {
+ fprintf(stderr, "ERROR: Storing secret failed\n");
+ }
+ else if ((success) && (secret) && (secret_len > 0))
+ {
+ const char *old_name;
+
+ old_name = names;
+
+ if (old_name)
+ secret_operation_delete(app, old_name, NULL, NULL);
+ }
+}
+
+static void
+_account_secret_transfer(MESSENGER_Application *app,
+ const char *secret,
+ uint32_t secret_len,
+ gboolean success,
+ gboolean error,
+ gpointer user_data)
+{
+ g_assert((app) && (user_data));
+
+ char *names = user_data;
+
+ if (error)
+ {
+ fprintf(stderr, "ERROR: Looking up secret failed\n");
+ }
+ else if ((success) && (secret) && (secret_len > 0))
+ {
+ MESSENGER_SecretOperation *op;
+ const char *name;
+ char *old_name;
+
+ name = names;
+ old_name = strchr(names, '\0');
+
+ if (old_name)
+ old_name = g_strdup(old_name + 1);
+
+ op = secret_operation_store(
+ app,
+ name,
+ secret,
+ secret_len,
+ &_account_secret_transferred,
+ old_name
+ );
+
+ if (op)
+ secret_operation_own_user_data(op);
}
}
@@ -478,11 +553,50 @@ event_select_profile(MESSENGER_Application *app,
struct GNUNET_CHAT_Account *account = GNUNET_CHAT_message_get_account(msg);
- if (GNUNET_CHAT_KIND_CREATED_ACCOUNT == GNUNET_CHAT_message_get_kind(msg))
+ switch (GNUNET_CHAT_message_get_kind(msg))
{
- const char *name = GNUNET_CHAT_account_get_name(account);
+ case GNUNET_CHAT_KIND_CREATED_ACCOUNT:
+ {
+ const char *name;
+
+ application_chat_lock(app);
+ name = GNUNET_CHAT_account_get_name(account);
+ application_chat_unlock(app);
+
+ secret_operation_lookup(app, name, &_account_secret_lookup, account);
+ break;
+ }
+ case GNUNET_CHAT_KIND_UPDATE_ACCOUNT:
+ {
+ MESSENGER_SecretOperation *op;
+ const char *old_name;
+ const char *name;
+ char *names;
+
+ application_chat_lock(app);
+ old_name = GNUNET_CHAT_message_get_text(msg);
+ name = GNUNET_CHAT_account_get_name(account);
+ application_chat_unlock(app);
+
+ if ((!old_name) || (!name))
+ break;
+
+ names = g_malloc(strlen(name) + strlen(old_name) + 2);
- secret_operation_lookup(app, name, &_account_secret_lookup, account);
+ if (names)
+ {
+ strcpy(names, name);
+ strcpy(names + strlen(name) + 1, old_name);
+ }
+
+ op = secret_operation_lookup(app, old_name, &_account_secret_transfer, names);
+
+ if (op)
+ secret_operation_own_user_data(op);
+ break;
+ }
+ default:
+ break;
}
}
diff --git a/src/secret.c b/src/secret.c
@@ -80,9 +80,12 @@ _secret_operation_new(MESSENGER_Application *application,
MESSENGER_SecretOperation* op = g_malloc(sizeof(MESSENGER_SecretOperation));
op->application = application;
+
op->callback = callback;
op->cancellable = cancellable;
op->user_data = user_data;
+ op->ownership = FALSE;
+
op->secret = NULL;
op->secret_len = 0;
@@ -312,6 +315,14 @@ secret_operation_delete(MESSENGER_Application *application,
}
void
+secret_operation_own_user_data(MESSENGER_SecretOperation *op)
+{
+ g_assert(op);
+
+ op->ownership = TRUE;
+}
+
+void
secret_operation_cancel(MESSENGER_SecretOperation *op)
{
g_assert(op);
@@ -334,6 +345,12 @@ secret_operation_cleanup(MESSENGER_SecretOperation *op)
GNUNET_free(op->secret);
}
+ if ((op->ownership) && (op->user_data))
+ {
+ g_free(op->user_data);
+ op->user_data = NULL;
+ }
+
if (!op->cancellable)
return;
diff --git a/src/secret.h b/src/secret.h
@@ -42,9 +42,12 @@ typedef void (*MESSENGER_SecretCallback)(
typedef struct MESSENGER_SecretOperation {
MESSENGER_Application *application;
+
MESSENGER_SecretCallback callback;
GCancellable *cancellable;
gpointer user_data;
+ gboolean ownership;
+
char *secret;
uint32_t secret_len;
} MESSENGER_SecretOperation;
@@ -100,6 +103,9 @@ secret_operation_delete(MESSENGER_Application *application,
gpointer user_data);
void
+secret_operation_own_user_data(MESSENGER_SecretOperation *op);
+
+void
secret_operation_cancel(MESSENGER_SecretOperation *op);
void
diff --git a/src/ui.c b/src/ui.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2022--2024 GNUnet e.V.
+ Copyright (C) 2022--2026 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -112,7 +112,7 @@ ui_label_set_markup_text(GtkLabel *label,
if (error)
{
- fprintf (stderr, "%s\n", error->message);
+ fprintf (stderr, "ERROR: %s\n", error->message);
g_error_free(error);
}