libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

commit 051e2f64428217295b0c73c22766fd477bfd5dc2
parent 61d6c29d3ec85d30fee2e5bfda39fedae589f24b
Author: Jacki <jacki@thejackimonster.de>
Date:   Fri, 16 Jan 2026 21:01:25 +0100

Move libsecret dependency to application level for compatibility

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Minclude/gnunet/gnunet_chat_lib.h | 10++++++++--
Mmeson.build | 3---
Msrc/gnunet_chat_account.c | 142-------------------------------------------------------------------------------
Msrc/gnunet_chat_account.h | 25-------------------------
Dsrc/gnunet_chat_account_intern.c | 190-------------------------------------------------------------------------------
Msrc/gnunet_chat_handle.c | 20++++++++++++++------
Msrc/gnunet_chat_handle.h | 7+++++--
Msrc/gnunet_chat_lib.c | 30++++++++++++++++++++++++++----
Msrc/gnunet_chat_lib_intern.c | 37+++++++++++++++++++++++++++++++------
Mtests/attribute/test_gnunet_chat_attribute_check.c | 17++++++++++++-----
Mtests/attribute/test_gnunet_chat_attribute_share.c | 26++++++++++++++++++--------
Mtests/discourse/test_gnunet_chat_discourse_open.c | 17++++++++++++-----
Mtests/discourse/test_gnunet_chat_discourse_write.c | 11+++++++++--
Mtests/file/test_gnunet_chat_file_send.c | 11+++++++++--
Mtests/group/test_gnunet_chat_group_open.c | 15+++++++++++----
Mtests/handle/meson.build | 11++++++++++-
Mtests/handle/test_gnunet_chat_handle_connection.c | 13++++++++++---
Atests/handle/test_gnunet_chat_handle_no_secret.c | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/handle/test_gnunet_chat_handle_rename.c | 11+++++++++--
Mtests/handle/test_gnunet_chat_handle_update.c | 11+++++++++--
Mtests/lobby/test_gnunet_chat_lobby_join.c | 13++++++++++---
Mtests/lobby/test_gnunet_chat_lobby_open.c | 13++++++++++---
Mtests/meson.build | 3++-
Mtests/message/test_gnunet_chat_message_text.c | 17++++++++++++-----
Mtests/tag/test_gnunet_chat_tag_contact.c | 11+++++++++--
Mtests/tag/test_gnunet_chat_tag_message.c | 11+++++++++--
Mtools/gnunet_chat_lib_uml.c | 18++++++++++++++++--
27 files changed, 391 insertions(+), 432 deletions(-)

diff --git a/include/gnunet/gnunet_chat_lib.h b/include/gnunet/gnunet_chat_lib.h @@ -600,14 +600,20 @@ GNUNET_CHAT_find_account (const struct GNUNET_CHAT_Handle *handle, const char *name); /** - * Connects a chat <i>handle</i> to a selected chat <i>account</i>. + * Connects a chat <i>handle</i> to a selected chat <i>account</i> using + * an optional secret for that account to encrypt/decrypt local keys + * in storage for end-to-end encrypted messages. * * @param[in,out] handle Chat handle * @param[in,out] account Chat account + * @param[in] secret Chat account secret or NULL + * @param[in] secret_len Length of secret or zero */ void GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account); + struct GNUNET_CHAT_Account *account, + const char *secret, + uint32_t secret_len); /** * Disconnects a chat <i>handle</i> from the current chat account. diff --git a/meson.build b/meson.build @@ -45,9 +45,6 @@ gnunetchat_deps = [ dependency('gnunetreclaim'), dependency('gnunetregex'), dependency('gnunetutil'), - - dependency('glib-2.0'), - dependency('libsecret-1'), ] subdir('include') diff --git a/src/gnunet_chat_account.c b/src/gnunet_chat_account.c @@ -29,11 +29,7 @@ #include <gnunet/gnunet_common.h> #include <gnunet/gnunet_identity_service.h> #include <gnunet/gnunet_messenger_service.h> - #include <gnunet/gnunet_util_lib.h> -#include <libsecret/secret.h> - -#include "gnunet_chat_account_intern.c" struct GNUNET_CHAT_Account* account_create (struct GNUNET_CHAT_Handle *handle, @@ -52,22 +48,8 @@ account_create (struct GNUNET_CHAT_Handle *handle, util_set_name_field(name, &(account->name)); - memset(&(account->secret), 0, sizeof(account->secret)); - account->cancellable = NULL; - account->user_pointer = NULL; - account->cancellable = g_cancellable_new(); - secret_password_lookup( - CHAT_ACCOUNT_SECRET_SCHEMA, - account->cancellable, - on_account_secret_lookup, - account, - "name", name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - return account; } @@ -107,82 +89,6 @@ account_get_name (const struct GNUNET_CHAT_Account *account) return account->name; } -const struct GNUNET_HashCode* -account_get_secret (struct GNUNET_CHAT_Account *account) -{ - GNUNET_assert(account); - - if (!(account->cancellable)) - return &(account->secret); - - g_cancellable_cancel(account->cancellable); - g_object_unref(account->cancellable); - account->cancellable = NULL; - - GError *error = NULL; - const char *name = account_get_name(account); - - gchar *password = secret_password_lookup_sync( - CHAT_ACCOUNT_SECRET_SCHEMA, - account->cancellable, - &error, - "name", name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - - if (error) - handle_account_secret_error(account, error); - else if (password) - { - GNUNET_CRYPTO_hash( - password, - g_utf8_strlen(password, -1), - &(account->secret) - ); - - secret_password_free(password); - } - else - { - struct GNUNET_HashCode raw_secret; - - GNUNET_CRYPTO_random_block( - GNUNET_CRYPTO_QUALITY_STRONG, - &raw_secret, sizeof(raw_secret) - ); - - const char *secret_value = GNUNET_h2s_full(&raw_secret); - - GNUNET_CRYPTO_hash_from_string( - secret_value, - &(account->secret) - ); - - char *desc = CHAT_ACCOUNT_DESC(name); - - secret_password_store_sync( - CHAT_ACCOUNT_SECRET_SCHEMA, - SECRET_COLLECTION_DEFAULT, - desc, - secret_value, - account->cancellable, - &error, - "name", name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - - if (desc) - GNUNET_free(desc); - - if (error) - handle_account_secret_error(account, error); - } - - return &(account->secret); -} - void account_update_ego (struct GNUNET_CHAT_Account *account, struct GNUNET_CHAT_Handle *handle, @@ -227,54 +133,6 @@ account_delete (struct GNUNET_CHAT_Account *account) GNUNET_assert(account); // TODO: clear namestore entries - - drop_account_secret(account); -} - -void -account_rename (struct GNUNET_CHAT_Account *account, - const char *new_name) -{ - GNUNET_assert(account); - - GError *error = NULL; - const char *name = account_get_name(account); - - gchar *password = secret_password_lookup_sync( - CHAT_ACCOUNT_SECRET_SCHEMA, - account->cancellable, - &error, - "name", name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - - if (error) - handle_account_secret_error(account, error); - else if (password) - { - char *desc = CHAT_ACCOUNT_DESC(new_name); - - secret_password_store_sync( - CHAT_ACCOUNT_SECRET_SCHEMA, - SECRET_COLLECTION_DEFAULT, - desc, - password, - account->cancellable, - &error, - "name", new_name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - - if (desc) - GNUNET_free(desc); - - secret_password_free(password); - handle_account_secret_error(account, error); - } - - drop_account_secret(account); } void diff --git a/src/gnunet_chat_account.h b/src/gnunet_chat_account.h @@ -29,9 +29,6 @@ #include <gnunet/gnunet_identity_service.h> #include <gnunet/gnunet_util_lib.h> -#include <glib-2.0/gio/gio.h> -#include <libsecret/secret.h> - struct GNUNET_CHAT_Handle; struct GNUNET_CHAT_Account @@ -42,8 +39,6 @@ struct GNUNET_CHAT_Account enum GNUNET_GenericReturnValue created; char *name; - struct GNUNET_HashCode secret; - GCancellable *cancellable; void *user_pointer; }; @@ -93,16 +88,6 @@ const char* account_get_name (const struct GNUNET_CHAT_Account *account); /** - * Returns the secret for local key storage from a given - * chat <i>account</i>. - * - * @param[in] account Chat account - * @return Secret or NULL - */ -const struct GNUNET_HashCode* -account_get_secret (struct GNUNET_CHAT_Account *account); - -/** * Updates the key from a given chat <i>account</i> using * the chat <i>handle</i> and a specific <i>ego</i> matching * the accounts name. @@ -125,16 +110,6 @@ void account_delete (struct GNUNET_CHAT_Account *account); /** - * Updates a chat <i>account</i> name related metadata. - * - * @param[in,out] account Chat account - * @param[in] new_name New name - */ -void -account_rename (struct GNUNET_CHAT_Account *account, - const char *new_name); - -/** * Destroys a chat <i>account</i> and frees its memory. * * @param[in,out] account Chat account diff --git a/src/gnunet_chat_account_intern.c b/src/gnunet_chat_account_intern.c @@ -1,190 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 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 - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - - SPDX-License-Identifier: AGPL3.0-or-later - */ -/* - * @author Tobias Frisch - * @file gnunet_chat_account_intern.c - */ - -#include <gnunet/gnunet_util_lib.h> -#include <libsecret/secret.h> - -const SecretSchema * account_secret_schema (void) G_GNUC_CONST; - -#define CHAT_ACCOUNT_SECRET_SCHEMA account_secret_schema() -#define CHAT_ACCOUNT_DESC(name) account_secret_description(name) -#define CHAT_ACCOUNT_APP_ID "org.gnunet.Messenger" - -const SecretSchema * -account_secret_schema(void) -{ - static const SecretSchema the_schema = { - "org.gnunet.chat.AccountSecret", SECRET_SCHEMA_NONE, - { - { "name", SECRET_SCHEMA_ATTRIBUTE_STRING }, - { "app_id", SECRET_SCHEMA_ATTRIBUTE_STRING }, - { "NULL", 0 }, - } - }; - return &the_schema; -} - -char* -account_secret_description(const char *name) -{ - char *desc; - - GNUNET_asprintf( - &desc, - "GNUnet Messenger account secret for identity %s", - name - ); - - return desc; -} - -static void -handle_account_secret_error(struct GNUNET_CHAT_Account *account, - GError *error) -{ - GNUNET_assert(account); - - if (!error) - return; - - if (error->message) - handle_send_internal_message( - account->handle, - account, - NULL, - GNUNET_CHAT_KIND_WARNING, - error->message, - GNUNET_NO - ); - - g_error_free(error); -} - -static void -on_account_secret_stored (GNUNET_UNUSED GObject *source, - GAsyncResult *result, - gpointer cls) -{ - GNUNET_assert((result) && (cls)); - - struct GNUNET_CHAT_Account *account = cls; - GError *error = NULL; - - secret_password_store_finish(result, &error); - - if (account->cancellable) - { - g_object_unref(account->cancellable); - account->cancellable = NULL; - } - - handle_account_secret_error(account, error); -} - -static void -on_account_secret_lookup (GNUNET_UNUSED GObject *source, - GAsyncResult *result, - gpointer cls) -{ - GNUNET_assert((result) && (cls)); - - struct GNUNET_CHAT_Account *account = cls; - GError *error = NULL; - - gchar *password = secret_password_lookup_finish(result, &error); - - if (account->cancellable) - { - g_object_unref(account->cancellable); - account->cancellable = NULL; - } - - if (error) - handle_account_secret_error(account, error); - else if (password) - { - GNUNET_CRYPTO_hash( - password, - g_utf8_strlen(password, -1), - &(account->secret) - ); - - secret_password_free(password); - } - else - { - struct GNUNET_HashCode raw_secret; - - GNUNET_CRYPTO_random_block( - GNUNET_CRYPTO_QUALITY_STRONG, - &raw_secret, sizeof(raw_secret) - ); - - const char *secret_value = GNUNET_h2s_full(&raw_secret); - const char *name = account_get_name(account); - - GNUNET_CRYPTO_hash_from_string( - secret_value, - &(account->secret) - ); - - char *desc = CHAT_ACCOUNT_DESC(name); - - secret_password_store( - CHAT_ACCOUNT_SECRET_SCHEMA, - SECRET_COLLECTION_DEFAULT, - desc, - secret_value, - account->cancellable, - on_account_secret_stored, - account, - "name", name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - - if (desc) - GNUNET_free(desc); - } -} - -static void -drop_account_secret(struct GNUNET_CHAT_Account *account) -{ - GNUNET_assert(account); - - GError *error = NULL; - const char *name = account_get_name(account); - - secret_password_clear_sync( - CHAT_ACCOUNT_SECRET_SCHEMA, - account->cancellable, - &error, - "name", name, - "app_id", CHAT_ACCOUNT_APP_ID, - NULL - ); - - handle_account_secret_error(account, error); -} diff --git a/src/gnunet_chat_handle.c b/src/gnunet_chat_handle.c @@ -98,6 +98,7 @@ handle_create_from_config (const struct GNUNET_CONFIGURATION_Handle* cfg, handle->own_contact = NULL; handle->next = NULL; + handle->next_secret = NULL; handle->current = NULL; handle->monitor = NULL; @@ -202,6 +203,17 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle) if (handle->current) handle_disconnect(handle); + if (handle->next_secret) + { + GNUNET_CRYPTO_zero_keys( + handle->next_secret, + sizeof(*(handle->next_secret)) + ); + + GNUNET_free(handle->next_secret); + handle->next_secret = NULL; + } + GNUNET_CONTAINER_multihashmap_iterate( handle->files, it_destroy_handle_files, NULL ); @@ -331,7 +343,8 @@ handle_update_identity(struct GNUNET_CHAT_Handle *handle) void handle_connect (struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account) + struct GNUNET_CHAT_Account *account, + const struct GNUNET_HashCode *secret) { GNUNET_assert( (handle) && (account) && @@ -365,9 +378,6 @@ handle_connect (struct GNUNET_CHAT_Handle *handle, const char *name = account_get_name(account); - const struct GNUNET_HashCode *secret; - secret = account_get_secret(account); - handle->messenger = GNUNET_MESSENGER_connect( handle->cfg, name, key, secret, on_handle_message, @@ -708,8 +718,6 @@ handle_rename_account (struct GNUNET_CHAT_Handle *handle, if (GNUNET_OK != result) return result; - account_rename(accounts->account, new_name); - accounts->op = GNUNET_IDENTITY_rename( handle->identity, old_name, diff --git a/src/gnunet_chat_handle.h b/src/gnunet_chat_handle.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021--2025 GNUnet e.V. + Copyright (C) 2021--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 @@ -111,6 +111,7 @@ struct GNUNET_CHAT_Handle struct GNUNET_CHAT_Contact *own_contact; struct GNUNET_CHAT_Account *next; + struct GNUNET_HashCode *next_secret; struct GNUNET_CHAT_Account *current; struct GNUNET_NAMESTORE_ZoneMonitor *monitor; @@ -182,10 +183,12 @@ handle_destroy (struct GNUNET_CHAT_Handle *handle); * * @param[in,out] handle Chat handle * @param[in] account Chat account + * @param[in] secret Chat account secret or NULL */ void handle_connect (struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account); + struct GNUNET_CHAT_Account *account, + const struct GNUNET_HashCode *secret); /** * Disconnects a given chat <i>handle</i> from its current diff --git a/src/gnunet_chat_lib.c b/src/gnunet_chat_lib.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021--2025 GNUnet e.V. + Copyright (C) 2021--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 @@ -184,7 +184,9 @@ GNUNET_CHAT_find_account (const struct GNUNET_CHAT_Handle *handle, void GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle, - struct GNUNET_CHAT_Account *account) + struct GNUNET_CHAT_Account *account, + const char *secret, + uint32_t secret_len) { GNUNET_CHAT_VERSION_ASSERT(); @@ -201,15 +203,35 @@ GNUNET_CHAT_connect (struct GNUNET_CHAT_Handle *handle, return; } + handle->next = account; + + if (handle->next_secret) + { + GNUNET_CRYPTO_zero_keys( + handle->next_secret, + sizeof(*(handle->next_secret)) + ); + + GNUNET_free(handle->next_secret); + } + + if ((secret) && (secret_len > 0)) + { + handle->next_secret = GNUNET_new(struct GNUNET_HashCode); + + if (handle->next_secret) + GNUNET_CRYPTO_hash(secret, secret_len, handle->next_secret); + } + else + handle->next_secret = NULL; + if (handle->current) { - handle->next = account; handle->connection = NULL; GNUNET_CHAT_disconnect(handle); return; } - handle->next = account; handle->connection = GNUNET_SCHEDULER_add_now( task_handle_connection, handle diff --git a/src/gnunet_chat_lib_intern.c b/src/gnunet_chat_lib_intern.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021--2025 GNUnet e.V. + Copyright (C) 2021--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 @@ -82,9 +82,37 @@ task_handle_connection (void *cls) return; struct GNUNET_CHAT_Account *account = handle->next; + struct GNUNET_HashCode local_secret; + const struct GNUNET_HashCode *secret; + + if (handle->next_secret) + { + GNUNET_memcpy( + &local_secret, + handle->next_secret, + sizeof(local_secret) + ); + + secret = &local_secret; + + GNUNET_CRYPTO_zero_keys( + handle->next_secret, + sizeof(*(handle->next_secret)) + ); + + GNUNET_free(handle->next_secret); + handle->next_secret = NULL; + } + else + secret = NULL; + handle->next = NULL; + handle_connect(handle, account, secret); - handle_connect(handle, account); + GNUNET_CRYPTO_zero_keys( + &local_secret, + sizeof(local_secret) + ); } void @@ -100,10 +128,7 @@ task_handle_disconnection (void *cls) if (! handle->next) return; - struct GNUNET_CHAT_Account *account = handle->next; - handle->next = NULL; - - handle_connect(handle, account); + task_handle_connection(cls); } void diff --git a/tests/attribute/test_gnunet_chat_attribute_check.c b/tests/attribute/test_gnunet_chat_attribute_check.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -24,9 +24,10 @@ #include "test_gnunet_chat.h" -#define TEST_CHECK_ID "gnunet_chat_attribute_check" -#define TEST_CHECK_NAME "test_attribute_check_name" -#define TEST_CHECK_VALUE "test_attribute_check_value" +#define TEST_CHECK_ID "gnunet_chat_attribute_check" +#define TEST_CHECK_NAME "test_attribute_check_name" +#define TEST_CHECK_VALUE "test_attribute_check_value" +#define TEST_CHECK_SECRET "test_secret_attribute_check" enum GNUNET_GenericReturnValue on_gnunet_chat_attribute_check_attr(void *cls, @@ -84,7 +85,13 @@ on_gnunet_chat_attribute_check_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_CHECK_SECRET, + strlen(TEST_CHECK_SECRET) + ); + attribute_stage = 1; } diff --git a/tests/attribute/test_gnunet_chat_attribute_share.c b/tests/attribute/test_gnunet_chat_attribute_share.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -24,11 +24,13 @@ #include "test_gnunet_chat.h" -#define TEST_SHARE_ID_A "gnunet_chat_attribute_share_a" -#define TEST_SHARE_ID_B "gnunet_chat_attribute_share_b" -#define TEST_SHARE_GROUP "test_attribute_share_group" -#define TEST_SHARE_NAME "test_attribute_share_name" -#define TEST_SHARE_VALUE "test_attribute_share_value" +#define TEST_SHARE_ID_A "gnunet_chat_attribute_share_a" +#define TEST_SHARE_ID_B "gnunet_chat_attribute_share_b" +#define TEST_SHARE_GROUP "test_attribute_share_group" +#define TEST_SHARE_NAME "test_attribute_share_name" +#define TEST_SHARE_VALUE "test_attribute_share_value" +#define TEST_SHARE_SECRET_A "test_secret_attribute_share_a" +#define TEST_SHARE_SECRET_B "test_secret_attribute_share_b" enum GNUNET_GenericReturnValue on_gnunet_chat_attribute_share_attr(void *cls, @@ -102,7 +104,13 @@ on_gnunet_chat_attribute_share_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_SHARE_SECRET_A, + strlen(TEST_SHARE_SECRET_A) + ); + share_stage = 1; } @@ -184,7 +192,9 @@ on_gnunet_chat_attribute_share_msg(void *cls, GNUNET_CHAT_connect( handle, - GNUNET_CHAT_find_account(handle, TEST_SHARE_ID_B) + GNUNET_CHAT_find_account(handle, TEST_SHARE_ID_B), + TEST_SHARE_SECRET_B, + strlen(TEST_SHARE_SECRET_B) ); share_stage = 3; diff --git a/tests/discourse/test_gnunet_chat_discourse_open.c b/tests/discourse/test_gnunet_chat_discourse_open.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -24,9 +24,10 @@ #include "test_gnunet_chat.h" -#define TEST_OPEN_ID "gnunet_chat_discourse_open" -#define TEST_OPEN_GROUP "gnunet_chat_discourse_open_group" -#define TEST_OPEN_DISCOURSE "gnunet_chat_discourse_open_discourse" +#define TEST_OPEN_ID "gnunet_chat_discourse_open" +#define TEST_OPEN_GROUP "gnunet_chat_discourse_open_group" +#define TEST_OPEN_DISCOURSE "gnunet_chat_discourse_open_discourse" +#define TEST_OPEN_SECRET "test_secret_discourse_open" enum GNUNET_GenericReturnValue on_gnunet_chat_discourse_open_msg(void *cls, @@ -66,7 +67,13 @@ on_gnunet_chat_discourse_open_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_OPEN_SECRET, + strlen(TEST_OPEN_SECRET) + ); + discourse_stage = 1; } diff --git a/tests/discourse/test_gnunet_chat_discourse_write.c b/tests/discourse/test_gnunet_chat_discourse_write.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -27,6 +27,7 @@ #define TEST_WRITE_ID "gnunet_chat_discourse_write" #define TEST_WRITE_GROUP "gnunet_chat_discourse_write_group" #define TEST_WRITE_DISCOURSE "gnunet_chat_discourse_write_discourse" +#define TEST_WRITE_SECRET "test_secret_discourse_write" enum GNUNET_GenericReturnValue on_gnunet_chat_discourse_write_msg(void *cls, @@ -66,7 +67,13 @@ on_gnunet_chat_discourse_write_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_WRITE_SECRET, + strlen(TEST_WRITE_SECRET) + ); + discourse_stage = 1; } diff --git a/tests/file/test_gnunet_chat_file_send.c b/tests/file/test_gnunet_chat_file_send.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 @@ -28,6 +28,7 @@ #define TEST_SEND_TEXT "gnunet_chat_file_deleted" #define TEST_SEND_FILENAME "gnunet_chat_file_send_name" #define TEST_SEND_GROUP "gnunet_chat_file_send_group" +#define TEST_SEND_SECRET "test_secret_file_send" void on_gnunet_chat_file_send_upload(void *cls, @@ -107,7 +108,13 @@ on_gnunet_chat_file_send_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_SEND_SECRET, + strlen(TEST_SEND_SECRET) + ); + file_stage = 1; } diff --git a/tests/group/test_gnunet_chat_group_open.c b/tests/group/test_gnunet_chat_group_open.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -24,8 +24,9 @@ #include "test_gnunet_chat.h" -#define TEST_OPEN_ID "gnunet_chat_group_open" -#define TEST_OPEN_GROUP "gnunet_chat_group_open_group" +#define TEST_OPEN_ID "gnunet_chat_group_open" +#define TEST_OPEN_GROUP "gnunet_chat_group_open_group" +#define TEST_OPEN_SECRET "test_secret_group_open" enum GNUNET_GenericReturnValue on_gnunet_chat_group_open_msg(void *cls, @@ -64,7 +65,13 @@ on_gnunet_chat_group_open_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_OPEN_SECRET, + strlen(TEST_OPEN_SECRET) + ); + group_stage = 1; } diff --git a/tests/handle/meson.build b/tests/handle/meson.build @@ -1,6 +1,6 @@ # # This file is part of GNUnet. -# Copyright (C) 2024 GNUnet e.V. +# Copyright (C) 2024--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 @@ -45,6 +45,15 @@ test_gnunet_chat_handle_init = executable( extra_files: test_header, ) +test_gnunet_chat_handle_no_secret = executable( + 'test_gnunet_chat_handle_no_secret.test', + 'test_gnunet_chat_handle_no_secret.c', + dependencies: test_deps, + link_with: gnunetchat_lib, + include_directories: tests_include, + extra_files: test_header, +) + test_gnunet_chat_handle_rename = executable( 'test_gnunet_chat_handle_rename.test', 'test_gnunet_chat_handle_rename.c', diff --git a/tests/handle/test_gnunet_chat_handle_connection.c b/tests/handle/test_gnunet_chat_handle_connection.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021--2024 GNUnet e.V. + Copyright (C) 2021--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 @@ -24,7 +24,8 @@ #include "test_gnunet_chat.h" -#define TEST_CONNECTION_ID "gnunet_chat_handle_connection" +#define TEST_CONNECTION_ID "gnunet_chat_handle_connection" +#define TEST_CONNECTION_SECRET "test_secret_handle_connection" enum GNUNET_GenericReturnValue on_gnunet_chat_handle_connection_msg(void *cls, @@ -63,7 +64,13 @@ on_gnunet_chat_handle_connection_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_CONNECTION_SECRET, + strlen(TEST_CONNECTION_SECRET) + ); + connection_stage = 1; } diff --git a/tests/handle/test_gnunet_chat_handle_no_secret.c b/tests/handle/test_gnunet_chat_handle_no_secret.c @@ -0,0 +1,130 @@ +/* + This file is part of GNUnet. + Copyright (C) 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 + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet 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 + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + SPDX-License-Identifier: AGPL3.0-or-later + */ +/* + * @author Tobias Frisch + * @file test_gnunet_chat_handle_no_secret.c + */ + +#include "test_gnunet_chat.h" + +#define TEST_NO_SECRET_ID "gnunet_chat_handle_no_secret" + +enum GNUNET_GenericReturnValue +on_gnunet_chat_handle_no_secret_msg(void *cls, + struct GNUNET_CHAT_Context *context, + struct GNUNET_CHAT_Message *message) +{ + static unsigned int secret_stage = 0; + + struct GNUNET_CHAT_Handle *handle = *( + (struct GNUNET_CHAT_Handle**) cls + ); + + ck_assert_ptr_nonnull(handle); + ck_assert_ptr_null(context); + ck_assert_ptr_nonnull(message); + + struct GNUNET_CHAT_Account *connected; + struct GNUNET_CHAT_Account *account; + const char *name; + + connected = GNUNET_CHAT_get_connected(handle); + account = GNUNET_CHAT_message_get_account(message); + + switch (GNUNET_CHAT_message_get_kind(message)) + { + case GNUNET_CHAT_KIND_WARNING: + ck_abort_msg("%s\n", GNUNET_CHAT_message_get_text(message)); + break; + case GNUNET_CHAT_KIND_REFRESH: + ck_assert_ptr_null(context); + ck_assert_ptr_null(account); + + if (secret_stage == 0) + { + account = GNUNET_CHAT_find_account(handle, TEST_NO_SECRET_ID); + + ck_assert_ptr_nonnull(account); + + GNUNET_CHAT_connect( + handle, + account, + NULL, + 0 + ); + + secret_stage = 1; + } + + break; + case GNUNET_CHAT_KIND_LOGIN: + ck_assert_ptr_nonnull(connected); + ck_assert_ptr_nonnull(account); + ck_assert_ptr_eq(connected, account); + ck_assert_uint_eq(secret_stage, 1); + + name = GNUNET_CHAT_account_get_name(account); + + ck_assert_ptr_nonnull(name); + ck_assert_str_eq(name, TEST_NO_SECRET_ID); + + GNUNET_CHAT_disconnect(handle); + secret_stage = 2; + break; + case GNUNET_CHAT_KIND_LOGOUT: + ck_assert_ptr_nonnull(connected); + ck_assert_ptr_nonnull(account); + ck_assert_ptr_eq(connected, account); + ck_assert_uint_eq(secret_stage, 2); + + name = GNUNET_CHAT_account_get_name(account); + + ck_assert_ptr_nonnull(name); + ck_assert_str_eq(name, TEST_NO_SECRET_ID); + + GNUNET_CHAT_stop(handle); + secret_stage = 3; + break; + default: + ck_abort(); + break; + } + + return GNUNET_YES; +} + +REQUIRE_GNUNET_CHAT_ACCOUNT(gnunet_chat_handle_connection, TEST_NO_SECRET_ID) + +void +call_gnunet_chat_handle_connection(const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + static struct GNUNET_CHAT_Handle *handle = NULL; + handle = GNUNET_CHAT_start(cfg, on_gnunet_chat_handle_no_secret_msg, &handle); + + ck_assert_ptr_nonnull(handle); +} + +CREATE_GNUNET_TEST(test_gnunet_chat_handle_connection, gnunet_chat_handle_connection) + +START_SUITE(handle_suite, "Handle (no secret)") +ADD_TEST_TO_SUITE(test_gnunet_chat_handle_connection, "Connect/Disconnect") +END_SUITE + +MAIN_SUITE(handle_suite, CK_NORMAL) diff --git a/tests/handle/test_gnunet_chat_handle_rename.c b/tests/handle/test_gnunet_chat_handle_rename.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021--2024 GNUnet e.V. + Copyright (C) 2021--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 @@ -26,6 +26,7 @@ #define TEST_RENAME_ID_A "gnunet_chat_handle_rename_a" #define TEST_RENAME_ID_B "gnunet_chat_handle_rename_b" +#define TEST_RENAME_SECRET "test_secret_rename" enum GNUNET_GenericReturnValue on_gnunet_chat_handle_rename_msg(void *cls, @@ -92,7 +93,13 @@ on_gnunet_chat_handle_rename_msg(void *cls, ck_assert_ptr_nonnull(account); ck_assert_uint_eq(rename_stage, 0); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_RENAME_SECRET, + strlen(TEST_RENAME_SECRET) + ); + rename_stage = 1; break; case GNUNET_CHAT_KIND_DELETED_ACCOUNT: diff --git a/tests/handle/test_gnunet_chat_handle_update.c b/tests/handle/test_gnunet_chat_handle_update.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2021--2024 GNUnet e.V. + Copyright (C) 2021--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 @@ -25,6 +25,7 @@ #include "test_gnunet_chat.h" #define TEST_UPDATE_ID "gnunet_chat_handle_update" +#define TEST_UPDATE_SECRET "test_secret_handle_update" enum GNUNET_GenericReturnValue on_gnunet_chat_handle_update_msg(void *cls, @@ -62,8 +63,14 @@ on_gnunet_chat_handle_update_msg(void *cls, ck_assert_ptr_nonnull(account); + GNUNET_CHAT_connect( + handle, + account, + TEST_UPDATE_SECRET, + strlen(TEST_UPDATE_SECRET) + ); + update_stage = 1; - GNUNET_CHAT_connect(handle, account); } break; diff --git a/tests/lobby/test_gnunet_chat_lobby_join.c b/tests/lobby/test_gnunet_chat_lobby_join.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 @@ -24,7 +24,8 @@ #include "test_gnunet_chat.h" -#define TEST_JOIN_ID "gnunet_chat_lobby_join" +#define TEST_JOIN_ID "gnunet_chat_lobby_join" +#define TEST_JOIN_SECRET "test_secret_lobby_join" void on_gnunet_chat_lobby_join_open(void *cls, @@ -71,7 +72,13 @@ on_gnunet_chat_lobby_join_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_JOIN_SECRET, + strlen(TEST_JOIN_SECRET) + ); + lobby_stage = 1; } diff --git a/tests/lobby/test_gnunet_chat_lobby_open.c b/tests/lobby/test_gnunet_chat_lobby_open.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 @@ -24,7 +24,8 @@ #include "test_gnunet_chat.h" -#define TEST_OPEN_ID "gnunet_chat_lobby_open" +#define TEST_OPEN_ID "gnunet_chat_lobby_open" +#define TEST_OPEN_SECRET "test_secret_lobby_open" enum GNUNET_GenericReturnValue on_gnunet_chat_lobby_open_msg(void *cls, @@ -61,7 +62,13 @@ on_gnunet_chat_lobby_open_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_OPEN_SECRET, + strlen(TEST_OPEN_SECRET) + ); + lobby_stage = 1; } diff --git a/tests/meson.build b/tests/meson.build @@ -1,6 +1,6 @@ # # This file is part of GNUnet. -# Copyright (C) 2023--2024 GNUnet e.V. +# Copyright (C) 2023--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 @@ -36,6 +36,7 @@ subdir('tag') test('test_gnunet_chat_handle_init', test_gnunet_chat_handle_init, depends: gnunetchat_lib, is_parallel : false) test('test_gnunet_chat_handle_accounts', test_gnunet_chat_handle_accounts, depends: gnunetchat_lib, is_parallel : false) +test('test_gnunet_chat_handle_no_secret', test_gnunet_chat_handle_no_secret, depends: gnunetchat_lib, is_parallel : false) test('test_gnunet_chat_handle_connection', test_gnunet_chat_handle_connection, depends: gnunetchat_lib, is_parallel : false) test('test_gnunet_chat_handle_update', test_gnunet_chat_handle_update, depends: gnunetchat_lib, is_parallel : false) test('test_gnunet_chat_handle_rename', test_gnunet_chat_handle_rename, depends: gnunetchat_lib, is_parallel : false) diff --git a/tests/message/test_gnunet_chat_message_text.c b/tests/message/test_gnunet_chat_message_text.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2023--2024 GNUnet e.V. + Copyright (C) 2023--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 @@ -24,9 +24,10 @@ #include "test_gnunet_chat.h" -#define TEST_TEXT_ID "gnunet_chat_message_text" -#define TEST_TEXT_GROUP "gnunet_chat_message_text_group" -#define TEST_TEXT_MSG "test_text_message" +#define TEST_TEXT_ID "gnunet_chat_message_text" +#define TEST_TEXT_GROUP "gnunet_chat_message_text_group" +#define TEST_TEXT_MSG "test_text_message" +#define TEST_TEXT_SECRET "test_secret_text" enum GNUNET_GenericReturnValue on_gnunet_chat_message_text_msg(void *cls, @@ -63,7 +64,13 @@ on_gnunet_chat_message_text_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_TEXT_SECRET, + strlen(TEST_TEXT_SECRET) + ); + text_stage = 1; } diff --git a/tests/tag/test_gnunet_chat_tag_contact.c b/tests/tag/test_gnunet_chat_tag_contact.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -27,6 +27,7 @@ #define TEST_TAG_ID "gnunet_chat_tag_contact" #define TEST_TAG_GROUP "gnunet_chat_tag_contact_group" #define TEST_TAG_CONTACT_TAG "test_contact_tag_tagged" +#define TEST_TAG_SECRET "test_secret_tag_contact" enum GNUNET_GenericReturnValue on_gnunet_chat_tag_contact_msg(void *cls, @@ -65,7 +66,13 @@ on_gnunet_chat_tag_contact_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_TAG_SECRET, + strlen(TEST_TAG_SECRET) + ); + tag_stage = 1; } diff --git a/tests/tag/test_gnunet_chat_tag_message.c b/tests/tag/test_gnunet_chat_tag_message.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -29,6 +29,7 @@ #define TEST_TAG_GROUP "gnunet_chat_tag_message_group" #define TEST_TAG_MSG "test_message_tag" #define TEST_TAG_MSG_TAG "test_message_tag_tagged" +#define TEST_TAG_SECRET "test_secret_tag_message" enum GNUNET_GenericReturnValue on_gnunet_chat_tag_message_msg(void *cls, @@ -65,7 +66,13 @@ on_gnunet_chat_tag_message_msg(void *cls, ck_assert_ptr_nonnull(account); - GNUNET_CHAT_connect(handle, account); + GNUNET_CHAT_connect( + handle, + account, + TEST_TAG_SECRET, + strlen(TEST_TAG_SECRET) + ); + tag_stage = 1; } diff --git a/tools/gnunet_chat_lib_uml.c b/tools/gnunet_chat_lib_uml.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2024 GNUnet e.V. + Copyright (C) 2024--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 @@ -35,6 +35,7 @@ struct GNUNET_CHAT_Tool char *account_name; char *group_name; char *contact_name; + char *secret; bool quit; }; @@ -49,7 +50,13 @@ accounts_iterate (void *cls, if (0 == strcmp(tool->account_name, account_name)) { - GNUNET_CHAT_connect(tool->handle, account); + GNUNET_CHAT_connect( + tool->handle, + account, + tool->secret, + tool->secret? strlen(tool->secret) : 0 + ); + return GNUNET_NO; } @@ -258,6 +265,13 @@ main (int argc, "name of group chat to read messages from", &(tool.group_name) ), + GNUNET_GETOPT_option_string( + 'S', + "secret", + "SECRET", + "storage secret for local keys", + &(tool.secret) + ), GNUNET_GETOPT_OPTION_END };