Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package otpclient for openSUSE:Factory checked in at 2023-02-10 14:35:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/otpclient (Old) and /work/SRC/openSUSE:Factory/.otpclient.new.1848 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "otpclient" Fri Feb 10 14:35:53 2023 rev:23 rq:1064195 version:3.1.4 Changes: -------- --- /work/SRC/openSUSE:Factory/otpclient/otpclient.changes 2023-01-14 00:04:14.394068133 +0100 +++ /work/SRC/openSUSE:Factory/.otpclient.new.1848/otpclient.changes 2023-02-10 14:35:54.162129322 +0100 @@ -1,0 +2,9 @@ +Fri Feb 10 09:41:55 UTC 2023 - Paolo Stivanin <i...@paolostivanin.com> + +- Update to 3.1.4: + * make auto-lock and secret service mutually exclusive (#279) + * fix importing plain AEGIS (#281) + * fix importing encrypted AEGIS on some distros (#281) + * rename disable_secret_service setting to use_secret_service + +------------------------------------------------------------------- Old: ---- v3.1.3.tar.gz v3.1.3.tar.gz.asc New: ---- v3.1.4.tar.gz v3.1.4.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ otpclient.spec ++++++ --- /var/tmp/diff_new_pack.6OeDFa/_old 2023-02-10 14:35:54.714132621 +0100 +++ /var/tmp/diff_new_pack.6OeDFa/_new 2023-02-10 14:35:54.722132668 +0100 @@ -18,7 +18,7 @@ %define uclname OTPClient Name: otpclient -Version: 3.1.3 +Version: 3.1.4 Release: 0 Summary: Simple GTK+ client for managing TOTP and HOTP License: GPL-3.0-or-later @@ -30,8 +30,7 @@ BuildRequires: cmake BuildRequires: gcc BuildRequires: gcc-c++ -BuildRequires: libbaseencode-devel >= 1.0.9 -BuildRequires: libcotp-devel >= 1.2.1 +BuildRequires: libcotp-devel >= 2.0.0 BuildRequires: libgcrypt-devel >= 1.6.0 BuildRequires: libjansson-devel >= 2.10.0 BuildRequires: libpng16-devel >= 1.6.0 ++++++ v3.1.3.tar.gz -> v3.1.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/CMakeLists.txt new/OTPClient-3.1.4/CMakeLists.txt --- old/OTPClient-3.1.3/CMakeLists.txt 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/CMakeLists.txt 2023-02-10 10:23:43.000000000 +0100 @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(OTPClient VERSION "3.1.3" LANGUAGES "C") +project(OTPClient VERSION "3.1.4" LANGUAGES "C") include(GNUInstallDirs) configure_file("src/common/version.h.in" "version.h") @@ -44,14 +44,14 @@ find_package(PkgConfig REQUIRED) find_package(Protobuf 3.6.0 REQUIRED) -find_package(Gcrypt 1.6.0 REQUIRED) -pkg_check_modules(COTP REQUIRED cotp>=1.2.1) +find_package(Gcrypt 1.8.0 REQUIRED) +pkg_check_modules(COTP REQUIRED cotp>=1.2.8) if(${COTP_VERSION} LESS 2.0.0) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DCOTP_OLD_LIB") - pkg_check_modules(BASEENCODE REQUIRED baseencode>=1.0.12) + pkg_check_modules(BASEENCODE REQUIRED baseencode>=1.0.15) endif() -pkg_check_modules(PNG REQUIRED libpng>=1.2.0) -pkg_check_modules(JANSSON REQUIRED jansson>=2.10.0) +pkg_check_modules(PNG REQUIRED libpng>=1.6.35) +pkg_check_modules(JANSSON REQUIRED jansson>=2.12) pkg_check_modules(ZBAR REQUIRED zbar>=0.20) pkg_check_modules(GTK3 REQUIRED gtk+-3.0>=3.20.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0>=2.64.0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/README.md new/OTPClient-3.1.4/README.md --- old/OTPClient-3.1.3/README.md 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/README.md 2023-02-10 10:23:43.000000000 +0100 @@ -14,15 +14,14 @@ |----------------------------------------------------|-------------| | GTK+ | 3.20 | | Glib | 2.48.0 | -| jansson | 2.10 | -| libgcrypt | 1.6.0 | -| libzip | 1.0.0 | -| libpng | 1.2.0 | -| [libbaseencode](https://github.com/paolostivanin/libbaseencode) | 1.0.12 | -| [libcotp](https://github.com/paolostivanin/libcotp) | 1.2.1 | +| jansson | 2.12 | +| libgcrypt | 1.8.0 | +| libpng | 1.6.35 | +| [libbaseencode](https://github.com/paolostivanin/libbaseencode) | 1.0.15 | +| [libcotp](https://github.com/paolostivanin/libcotp) | 1.2.8 | | zbar | 0.20 | -| protobuf-c | 1.30 | -| protobuf | 3.6 | +| protobuf-c | 1.3.0 | +| protobuf | 3.6.0 | | uuid | 2.34 | | libsecret | 0.20 | | qrencode | 4.0.2 | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/SECURITY.md new/OTPClient-3.1.4/SECURITY.md --- old/OTPClient-3.1.3/SECURITY.md 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/SECURITY.md 2023-02-10 10:23:43.000000000 +0100 @@ -5,18 +5,18 @@ The following list describes whether a version is eligible or not for security updates. | Version | Supported | EOL | -|---------| ------------------ |-------------| +|---------|--------------------|-------------| | 3.1.x | :heavy_check_mark: | - | -| 3.0.x | :x: | 31-Dec-2022 | -| 2.6.x | :heavy_check_mark: | 15-Jan-2023 | -| 2.5.x | :x: | 31-Aug-2022 | -| 2.4.x | :x: | 15-May-2022 | -| 2.3.x | :x: | 28-Feb-2021 | -| 2.2.x | :x: | 27-May-2020 | -| 2.1.x | :x: | 20-Apr-2020 | -| 2.0.x | :x: | 08-Mar-2020 | -| 1.5.x | :x: | 31-Mar-2020 | -| < 1.5.0 | :x: | 27-Jun-2019 | +| 3.0.x | :x: | 31-Dec-2022 | +| 2.6.x | :x: | 15-Jan-2023 | +| 2.5.x | :x: | 31-Aug-2022 | +| 2.4.x | :x: | 15-May-2022 | +| 2.3.x | :x: | 28-Feb-2021 | +| 2.2.x | :x: | 27-May-2020 | +| 2.1.x | :x: | 20-Apr-2020 | +| 2.0.x | :x: | 08-Mar-2020 | +| 1.5.x | :x: | 31-Mar-2020 | +| < 1.5.0 | :x: | 27-Jun-2019 | ## Reporting a Vulnerability diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/data/com.github.paolostivanin.OTPClient.appdata.xml new/OTPClient-3.1.4/data/com.github.paolostivanin.OTPClient.appdata.xml --- old/OTPClient-3.1.3/data/com.github.paolostivanin.OTPClient.appdata.xml 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/data/com.github.paolostivanin.OTPClient.appdata.xml 2023-02-10 10:23:43.000000000 +0100 @@ -83,6 +83,17 @@ </content_rating> <releases> + <release version="3.1.4" date="2023-02-06"> + <description> + <p>OTPClient 3.1.4 brings some fixes</p> + <ul> + <li>make auto-lock and secret service mutually exclusive (#279)</li> + <li>fix importing plain AEGIS (#281)</li> + <li>fix importing encrypted AEGIS on some distros (#281)</li> + <li>rename disable_secret_service setting to use_secret_service</li> + </ul> + </description> + </release> <release version="3.1.3" date="2023-01-12"> <description> <p>OTPClient 3.1.3 brings some fixes</p> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/app.c new/OTPClient-3.1.4/src/app.c --- old/OTPClient-3.1.3/src/app.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/app.c 2023-02-10 10:23:43.000000000 +0100 @@ -2,6 +2,7 @@ #include <gcrypt.h> #include <jansson.h> #include <libsecret/secret.h> +#include <glib/gi18n.h> #include "otpclient.h" #include "gquarks.h" #include "imports.h" @@ -28,12 +29,14 @@ static gchar *get_db_path (AppData *app_data); #endif -static GKeyFile *get_kf_ptr (void); - -static void get_wh_data (gint *width, +static void set_config_data (gint *width, gint *height, AppData *app_data); +static void migrate_secretservice_kf (AppData *app_data, + GKeyFile *kf, + gboolean value); + static gboolean get_warn_data (void); static void set_warn_data (gboolean show_warning); @@ -107,20 +110,20 @@ app_data->auto_lock = FALSE; // disabled by default app_data->inactivity_timeout = 0; // never app_data->use_dark_theme = FALSE; // light theme by default - app_data->disable_secret_service = FALSE; // secret service enabled by default + app_data->use_secret_service = TRUE; // secret service enabled by default app_data->is_reorder_active = FALSE; // when app is started, reorder is not set // open_db_file_action is set only on first startup and not when the db is deleted but the cfg file is there, therefore we need a default action app_data->open_db_file_action = GTK_FILE_CHOOSER_ACTION_SAVE; - get_wh_data (&width, &height, app_data); + app_data->builder = get_builder_from_partial_path (UI_PARTIAL_PATH); + + set_config_data (&width, &height, app_data); app_data->db_data = g_new0 (DatabaseData, 1); app_data->db_data->key_stored = FALSE; // at startup, we don't know whether the key is stored or not - app_data->builder = get_builder_from_partial_path (UI_PARTIAL_PATH); - create_main_window (width, height, app_data); if (app_data->main_window == NULL) { - g_printerr ("Couldn't locate the ui file, exiting...\n"); + g_printerr ("%s\n", _("Couldn't locate the ui file, exiting...")); g_free (app_data->db_data); g_application_quit (G_APPLICATION(app)); return; @@ -191,10 +194,10 @@ // subtract 3 seconds from the current time. Needed for "last_hotp" to be set on the first run app_data->db_data->last_hotp_update = g_date_time_add_seconds (g_date_time_new_now_local (), -(G_TIME_SPAN_SECOND * HOTP_RATE_LIMIT_IN_SEC)); - if (app_data->disable_secret_service == FALSE) { + if (app_data->use_secret_service == TRUE) { gchar *pwd = secret_password_lookup_sync (OTPCLIENT_SCHEMA, NULL, NULL, "string", "main_pwd", NULL); if (pwd == NULL) { - g_printerr ("Couldn't find the password in the secret service.\n"); + g_printerr ("%s\n", _("Couldn't find the password in the secret service.")); goto retry; } else { app_data->db_data->key_stored = TRUE; @@ -232,15 +235,15 @@ goto retry; } - if (app_data->disable_secret_service == FALSE && app_data->db_data->key_stored == FALSE) { + if (app_data->use_secret_service == TRUE && app_data->db_data->key_stored == FALSE) { secret_password_store (OTPCLIENT_SCHEMA, SECRET_COLLECTION_DEFAULT, "main_pwd", app_data->db_data->key, NULL, on_password_stored, NULL, "string", "main_pwd", NULL); } if (g_error_matches (err, missing_file_gquark(), MISSING_FILE_CODE)) { - const gchar *msg = "This is the first time you run OTPClient, so you need to <b>add</b> or <b>import</b> some tokens.\n" + const gchar *msg = _("This is the first time you run OTPClient, so you need to <b>add</b> or <b>import</b> some tokens.\n" "- to <b>add</b> tokens, please click the + button on the <b>top left</b>.\n" "- to <b>import</b> existing tokens, please click the menu button <b>on the top right</b>.\n" - "\nIf you need more info, please visit the <a href=\"https://github.com/paolostivanin/OTPClient/wiki\">project's wiki</a>"; + "\nIf you need more info, please visit the <a href=\"https://github.com/paolostivanin/OTPClient/wiki\">project's wiki</a>"); show_message_dialog (app_data->main_window, msg, GTK_MESSAGE_INFO); GError *tmp_err = NULL; update_and_reload_db (app_data, app_data->db_data, FALSE, &tmp_err); @@ -256,7 +259,7 @@ g_notification_set_priority (app_data->notification, G_NOTIFICATION_PRIORITY_NORMAL); GIcon *icon = g_themed_icon_new ("com.github.paolostivanin.OTPClient"); g_notification_set_icon (app_data->notification, icon); - g_notification_set_body (app_data->notification, "OTP value has been copied to the clipboard"); + g_notification_set_body (app_data->notification, _("OTP value has been copied to the clipboard")); g_object_unref (icon); GtkToggleButton *reorder_toggle_btn = GTK_TOGGLE_BUTTON(gtk_builder_get_object (app_data->builder, "reorder_toggle_btn_id")); @@ -283,7 +286,7 @@ app_data->info_bar = GTK_WIDGET(gtk_builder_get_object (app_data->builder, "info_bar_id")); if (show_upgrade_msg ()) { - set_info_bar (app_data, "Release <b>2.6.0</b>: please check the 'Secret Service Integration' new feature <a href=\"https://github.com/paolostivanin/OTPClient/wiki/How-to-use-OTPClient#secret-service-integration\">HERE</a>"); + set_info_bar (app_data, _("Not asking for password? Please check the 'Secret Service Integration' new feature <a href=\"https://github.com/paolostivanin/OTPClient/wiki/How-to-use-OTPClient#secret-service-integration\">HERE</a>")); } else { gtk_widget_hide (app_data->info_bar); } @@ -294,11 +297,11 @@ show_memlock_warn_dialog (gint32 max_file_size, GtkBuilder *builder) { - gchar *msg = g_strdup_printf ("Your OS's memlock limit (%d) may be too low for you. " + gchar *msg = g_strdup_printf (_("Your OS's memlock limit (%d) may be too low for you. " "This could crash the program when importing data from 3rd party apps " "or when a certain amount of tokens is reached. " "Please have a look at the <a href=\"https://github.com/paolostivanin/OTPClient/wiki/Secure-Memory-Limitations\">secure memory wiki</a> page before " - "using this software with the current settings.", max_file_size); + "using this software with the current settings."), max_file_size); GtkWidget *warn_diag = GTK_WIDGET(gtk_builder_get_object (builder, "warning_diag_id")); GtkLabel *warn_label = GTK_LABEL(gtk_builder_get_object (builder, "warning_diag_label_id")); GtkWidget *warn_chk_btn = GTK_WIDGET(gtk_builder_get_object (builder, "warning_diag_check_btn_id")); @@ -339,37 +342,14 @@ } -static GKeyFile * -get_kf_ptr (void) -{ - GError *err = NULL; - GKeyFile *kf = g_key_file_new (); - gchar *cfg_file_path; -#ifndef USE_FLATPAK_APP_FOLDER - cfg_file_path = g_build_filename (g_get_user_config_dir (), "otpclient.cfg", NULL); -#else - cfg_file_path = g_build_filename (g_get_user_data_dir (), "otpclient.cfg", NULL); -#endif - if (g_file_test (cfg_file_path, G_FILE_TEST_EXISTS)) { - if (g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, &err)) { - g_free (cfg_file_path); - return kf; - } - g_printerr ("%s\n", err->message); - g_clear_error (&err); - } - g_free (cfg_file_path); - g_key_file_free (kf); - return NULL; -} - - static void -get_wh_data (gint *width, - gint *height, - AppData *app_data) +set_config_data (gint *width, + gint *height, + AppData *app_data) { GKeyFile *kf = get_kf_ptr (); + GError *err = NULL; + gboolean tmp; if (kf != NULL) { *width = g_key_file_get_integer (kf, "config", "window_width", NULL); *height = g_key_file_get_integer (kf, "config", "window_height", NULL); @@ -379,13 +359,46 @@ app_data->auto_lock = g_key_file_get_boolean (kf, "config", "auto_lock", NULL); app_data->inactivity_timeout = g_key_file_get_integer (kf, "config", "inactivity_timeout", NULL); app_data->use_dark_theme = g_key_file_get_boolean (kf, "config", "dark_theme", NULL); - app_data->disable_secret_service = g_key_file_get_boolean (kf, "config", "disable_secret_service", NULL); + // handle migration from disable_secret_service to use_secret_service + tmp = g_key_file_get_boolean (kf, "config", "disable_secret_service", &err); + if (tmp == TRUE || (tmp == FALSE && err == NULL)) { + // old key was found, so we need to migrate to the new format + migrate_secretservice_kf (app_data, kf, !tmp); + } + if (tmp == FALSE && err != NULL) { + // key was not found, so we already migrated to the new format + app_data->use_secret_service = g_key_file_get_boolean (kf, "config", "use_secret_service", NULL); + } + // end migration g_object_set (gtk_settings_get_default (), "gtk-application-prefer-dark-theme", app_data->use_dark_theme, NULL); g_key_file_free (kf); } } +static void +migrate_secretservice_kf (AppData *app_data, + GKeyFile *kf, + gboolean value) +{ + GError *err = NULL; + app_data->use_secret_service = value; + g_key_file_set_boolean (kf, "config", "use_secret_service", app_data->use_secret_service); + g_key_file_remove_key (kf, "config", "disable_secret_service", NULL); + gchar *cfg_file_path; +#ifndef USE_FLATPAK_APP_FOLDER + cfg_file_path = g_build_filename (g_get_user_config_dir (), "otpclient.cfg", NULL); +#else + cfg_file_path = g_build_filename (g_get_user_data_dir (), "otpclient.cfg", NULL); +#endif + if (!g_key_file_save_to_file (kf, cfg_file_path, &err)) { + gchar *err_msg = g_strconcat (_("Couldn't save the config file: "), err->message, NULL); + show_message_dialog (app_data->main_window, err_msg, GTK_MESSAGE_ERROR); + g_free (err_msg); + g_clear_error (&err); + } +} + static gboolean get_warn_data (void) { @@ -440,6 +453,10 @@ GtkWidget *lock_btn = GTK_WIDGET(gtk_builder_get_object (app_data->builder, "lock_btn_id")); g_signal_connect (lock_btn, "clicked", G_CALLBACK(lock_app), app_data); + if (app_data->use_secret_service == TRUE) { + // secret service is enabled, so we can't lock the app + gtk_widget_set_sensitive (lock_btn, FALSE); + } set_action_group (app_data->builder, app_data); } @@ -586,7 +603,7 @@ goto end; } new_db: ; // empty statement workaround - GtkFileChooserNative *dialog = gtk_file_chooser_native_new ("Select database location", + GtkFileChooserNative *dialog = gtk_file_chooser_native_new (_("Select database location"), GTK_WINDOW (app_data->main_window), app_data->open_db_file_action, "OK", @@ -660,8 +677,8 @@ app_data->css_provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (app_data->css_provider, "#delbtn { background: #ff0033; }", -1, NULL); gtk_style_context_add_provider (gsc, GTK_STYLE_PROVIDER(app_data->css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); - const gchar *msg = "You just entered the deletion mode. You can now click on the row(s) you'd like to delete.\n" - "Please note that once a row has been deleted, <b>it's impossible to recover the associated data.</b>"; + const gchar *msg = _("You just entered the deletion mode. You can now click on the row(s) you'd like to delete.\n" + "Please note that once a row has been deleted, <b>it's impossible to recover the associated data.</b>"); if (get_confirmation_from_dialog (app_data->main_window, msg)) { g_signal_handlers_disconnect_by_func (app_data->tree_view, row_selected_cb, app_data); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/cli/main.c new/OTPClient-3.1.4/src/cli/main.c --- old/OTPClient-3.1.3/src/cli/main.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/cli/main.c 2023-02-10 10:23:43.000000000 +0100 @@ -13,12 +13,12 @@ #define MAX_ABS_PATH_LEN 256 #ifndef USE_FLATPAK_APP_FOLDER -static gchar *get_db_path (void); +static gchar *get_db_path (void); #endif -static gchar *get_pwd (const gchar *pwd_msg); +static gchar *get_pwd (const gchar *pwd_msg); -static gboolean is_secretservice_disable (void); +static gboolean get_use_secretservice (void); gint @@ -57,8 +57,8 @@ } #endif - gboolean disable_secret_service = is_secretservice_disable (); - if (disable_secret_service == FALSE) { + gboolean use_secret_service = get_use_secretservice (); + if (use_secret_service == TRUE) { gchar *pwd = secret_password_lookup_sync (OTPCLIENT_SCHEMA, NULL, NULL, "string", "main_pwd", NULL); if (pwd == NULL) { goto get_pwd; @@ -90,7 +90,7 @@ return -1; } - if (disable_secret_service == FALSE && db_data->key_stored == FALSE) { + if (use_secret_service == TRUE && db_data->key_stored == FALSE) { secret_password_store (OTPCLIENT_SCHEMA, SECRET_COLLECTION_DEFAULT, "main_pwd", db_data->key, NULL, on_password_stored, NULL, "string", "main_pwd", NULL); } @@ -284,9 +284,9 @@ static gboolean -is_secretservice_disable (void) +get_use_secretservice (void) { - gboolean disable_secret_service = FALSE; + gboolean use_secret_service = TRUE; // by default, we enable it GError *err = NULL; GKeyFile *kf = g_key_file_new (); gchar *cfg_file_path = g_build_filename (g_get_user_config_dir (), "otpclient.cfg", NULL); @@ -297,7 +297,7 @@ g_clear_error (&err); return FALSE; } - disable_secret_service = g_key_file_get_boolean (kf, "config", "disable_secret_service", NULL); + use_secret_service = g_key_file_get_boolean (kf, "config", "use_secret_service", NULL); } - return disable_secret_service; + return use_secret_service; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/common/aegis.c new/OTPClient-3.1.4/src/common/aegis.c --- old/OTPClient-3.1.3/src/common/aegis.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/common/aegis.c 2023-02-10 10:23:43.000000000 +0100 @@ -46,15 +46,14 @@ get_otps_from_plain_backup (const gchar *path, GError **err) { - gchar *plain_json_data; - gsize read_len; - if (!g_file_get_contents (path, &plain_json_data, &read_len, err)) { - g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "Error while getting file's content."); + json_error_t j_err; + json_t *json = json_load_file (path, 0, &j_err); + if (!json) { + g_printerr ("Error loading json: %s\n", j_err.text); return NULL; } - GSList *otps = parse_json_data (plain_json_data, err); - g_free (plain_json_data); + GSList *otps = parse_json_data (json_string_value (json_object_get (json, "db")), err); return otps; } @@ -67,17 +66,17 @@ GError **err) { json_error_t j_err; - json_t *json = json_load_file(path, 0, &j_err); + json_t *json = json_load_file (path, 0, &j_err); if (!json) { g_printerr ("Error loading json: %s\n", j_err.text); return NULL; } - json_t *arr = json_object_get(json_object_get(json, "header"), "slots"); + json_t *arr = json_object_get (json_object_get(json, "header"), "slots"); gint index = 0; for (; index < json_array_size(arr); index++) { - json_t *j_type = json_object_get(json_array_get(arr, index), "type"); - json_int_t int_type = json_integer_value(j_type); + json_t *j_type = json_object_get (json_array_get(arr, index), "type"); + json_int_t int_type = json_integer_value (j_type); if (int_type == 1) break; } json_t *wanted_obj = json_array_get (arr, index); @@ -154,7 +153,7 @@ } gsize out_len; - guchar *b64decoded_db = g_base64_decode_secure (json_string_value (json_object_get(json, "db")), &out_len); + guchar *b64decoded_db = g_base64_decode_secure (json_string_value (json_object_get (json, "db")), &out_len); if (out_len > max_file_size) { g_set_error (err, file_too_big_gquark (), FILE_TOO_BIG, "File is too big"); g_free (tag); @@ -203,7 +202,7 @@ { GError *err = NULL; json_t *root = json_object (); - json_object_set (root, "version", json_integer(1)); + json_object_set (root, "version", json_integer (1)); gcry_cipher_hd_t hd; guchar *derived_master_key = NULL, *enc_master_key = NULL, *key_nonce = NULL, *key_tag = NULL, *db_nonce = NULL, *db_tag = NULL, *salt = NULL; @@ -218,7 +217,7 @@ json_object_set (slot_1, "type", json_integer (1)); uuid_t binuuid; - uuid_generate_random(binuuid); + uuid_generate_random (binuuid); gchar *uuid = g_malloc0 (37); uuid_unparse_lower (binuuid, uuid); json_object_set (slot_1, "uuid", json_string (g_strdup (uuid))); @@ -286,7 +285,7 @@ json_t *aegis_db_obj = json_object (); json_t *array = json_array (); - json_object_set (aegis_db_obj, "version", json_integer(1)); + json_object_set (aegis_db_obj, "version", json_integer (2)); json_object_set (aegis_db_obj, "entries", array); json_object_set (root, "db", aegis_db_obj); @@ -395,12 +394,13 @@ GError **err) { json_error_t jerr; - json_t *root = json_loads (data, 0, &jerr); + json_t *root = json_loads (data, JSON_DISABLE_EOF_CHECK, &jerr); if (root == NULL) { g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "%s", jerr.text); return NULL; } - json_t *array = json_object_get(root, "entries"); + + json_t *array = json_object_get (root, "entries"); if (array == NULL) { g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "%s", jerr.text); json_decref (root); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/common/andotp.c new/OTPClient-3.1.4/src/common/andotp.c --- old/OTPClient-3.1.3/src/common/andotp.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/common/andotp.c 2023-02-10 10:23:43.000000000 +0100 @@ -332,7 +332,7 @@ GError **err) { json_error_t jerr; - json_t *array = json_loads (data, 0, &jerr); + json_t *array = json_loads (data, JSON_DISABLE_EOF_CHECK, &jerr); if (array == NULL) { g_set_error (err, generic_error_gquark (), GENERIC_ERRCODE, "%s", jerr.text); return NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/common/common.c new/OTPClient-3.1.4/src/common/common.c --- old/OTPClient-3.1.3/src/common/common.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/common/common.c 2023-02-10 10:23:43.000000000 +0100 @@ -424,3 +424,28 @@ return hd; } + + +GKeyFile * +get_kf_ptr (void) +{ + GError *err = NULL; + GKeyFile *kf = g_key_file_new (); + gchar *cfg_file_path; +#ifndef USE_FLATPAK_APP_FOLDER + cfg_file_path = g_build_filename (g_get_user_config_dir (), "otpclient.cfg", NULL); +#else + cfg_file_path = g_build_filename (g_get_user_data_dir (), "otpclient.cfg", NULL); +#endif + if (g_file_test (cfg_file_path, G_FILE_TEST_EXISTS)) { + if (g_key_file_load_from_file (kf, cfg_file_path, G_KEY_FILE_NONE, &err)) { + g_free (cfg_file_path); + return kf; + } + g_printerr ("%s\n", err->message); + g_clear_error (&err); + } + g_free (cfg_file_path); + g_key_file_free (kf); + return NULL; +} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/common/common.h new/OTPClient-3.1.4/src/common/common.h --- old/OTPClient-3.1.3/src/common/common.h 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/common/common.h 2023-02-10 10:23:43.000000000 +0100 @@ -49,4 +49,6 @@ guchar *iv, gsize iv_len); +GKeyFile *get_kf_ptr (void); + G_END_DECLS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/data.h new/OTPClient-3.1.4/src/data.h --- old/OTPClient-3.1.3/src/data.h 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/data.h 2023-02-10 10:23:43.000000000 +0100 @@ -60,7 +60,7 @@ gboolean is_reorder_active; - gboolean disable_secret_service; + gboolean use_secret_service; GDateTime *last_user_activity; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/settings-cb.c new/OTPClient-3.1.4/src/settings-cb.c --- old/OTPClient-3.1.3/src/settings-cb.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/settings-cb.c 2023-02-10 10:23:43.000000000 +0100 @@ -5,6 +5,31 @@ #include "message-dialogs.h" #include "get-builder.h" #include "secret-schema.h" +#include "common/common.h" + +typedef struct settings_data_t { + GtkWidget *dss_switch; + GtkWidget *al_switch; + GtkWidget *inactivity_cb; + AppData *app_data; +} SettingsData; + +static void handle_al_ss (AppData *app_data, + GtkWidget *al_switch, + GtkWidget *inactivity_cb, + GtkWidget *dss_switch); + +static gboolean handle_secretservice_switch (GtkSwitch *sw, + gboolean state, + gpointer user_data); + +static void handle_secretservice_combobox (GtkComboBox *cb, + gpointer user_data); + +static gboolean handle_autolock (GtkSwitch *sw, + gboolean state, + gpointer user_data); + void settings_dialog_cb (GSimpleAction *simple __attribute__((unused)), @@ -12,6 +37,8 @@ gpointer user_data) { AppData *app_data = (AppData *)user_data; + SettingsData *settings_data = g_new0 (SettingsData, 1); + settings_data->app_data = app_data; gchar *cfg_file_path; #ifndef USE_FLATPAK_APP_FOLDER @@ -39,52 +66,62 @@ app_data->auto_lock = g_key_file_get_boolean (kf, "config", "auto_lock", NULL); app_data->inactivity_timeout = g_key_file_get_integer (kf, "config", "inactivity_timeout", NULL); app_data->use_dark_theme = g_key_file_get_boolean (kf, "config", "dark_theme", NULL); - app_data->disable_secret_service = g_key_file_get_boolean (kf, "config", "disable_secret_service", NULL); + app_data->use_secret_service = g_key_file_get_boolean (kf, "config", "use_secret_service", &err); + if (err != NULL && g_error_matches (err, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) { + // if the key is not found, we set it to TRUE and save it to the config file. + app_data->use_secret_service = TRUE; + g_clear_error (&err); + } GtkBuilder *builder = get_builder_from_partial_path(UI_PARTIAL_PATH); GtkWidget *dialog = GTK_WIDGET(gtk_builder_get_object (builder, "settings_diag_id")); GtkWidget *sno_switch = GTK_WIDGET(gtk_builder_get_object (builder, "nextotp_switch_id")); GtkWidget *dn_switch = GTK_WIDGET(gtk_builder_get_object (builder, "notif_switch_id")); GtkWidget *sc_cb = GTK_WIDGET(gtk_builder_get_object (builder, "search_by_cb_id")); - GtkWidget *al_switch = GTK_WIDGET(gtk_builder_get_object (builder, "autolock_switch_id")); - GtkWidget *inactivity_cb = GTK_WIDGET(gtk_builder_get_object (builder, "autolock_inactive_cb_id")); + settings_data->al_switch = GTK_WIDGET(gtk_builder_get_object (builder, "autolock_switch_id")); + g_signal_connect (settings_data->al_switch, "state-set", G_CALLBACK(handle_secretservice_switch), settings_data); + settings_data->inactivity_cb = GTK_WIDGET(gtk_builder_get_object (builder, "autolock_inactive_cb_id")); + g_signal_connect (settings_data->inactivity_cb, "changed", G_CALLBACK(handle_secretservice_combobox), settings_data); GtkWidget *dt_switch = GTK_WIDGET(gtk_builder_get_object (builder, "dark_theme_switch_id")); - GtkWidget *dss_switch = GTK_WIDGET(gtk_builder_get_object (builder, "disable_secret_service_switch_id")); + settings_data->dss_switch = GTK_WIDGET(gtk_builder_get_object (builder, "secret_service_switch_id")); + g_signal_connect (settings_data->dss_switch, "state-set", G_CALLBACK(handle_autolock), settings_data); gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(app_data->main_window)); gtk_switch_set_active (GTK_SWITCH(sno_switch), app_data->show_next_otp); gtk_switch_set_active (GTK_SWITCH(dn_switch), app_data->disable_notifications); - gtk_switch_set_active (GTK_SWITCH(al_switch), app_data->auto_lock); + gtk_switch_set_active (GTK_SWITCH(settings_data->al_switch), app_data->auto_lock); gtk_switch_set_active (GTK_SWITCH(dt_switch), app_data->use_dark_theme); - gtk_switch_set_active (GTK_SWITCH(dss_switch), app_data->disable_secret_service); + gtk_switch_set_active (GTK_SWITCH(settings_data->dss_switch), app_data->use_secret_service); gchar *active_id_string = g_strdup_printf ("%d", app_data->search_column); gtk_combo_box_set_active_id (GTK_COMBO_BOX(sc_cb), active_id_string); g_free (active_id_string); active_id_string = g_strdup_printf ("%d", app_data->inactivity_timeout); - gtk_combo_box_set_active_id (GTK_COMBO_BOX(inactivity_cb), active_id_string); + gtk_combo_box_set_active_id (GTK_COMBO_BOX(settings_data->inactivity_cb), active_id_string); g_free (active_id_string); + handle_al_ss (app_data, settings_data->al_switch, settings_data->inactivity_cb, settings_data->dss_switch); + gtk_widget_show_all (dialog); - gboolean old_ss_value = app_data->disable_secret_service; + gboolean old_ss_value = app_data->use_secret_service; switch (gtk_dialog_run (GTK_DIALOG(dialog))) { case GTK_RESPONSE_OK: app_data->show_next_otp = gtk_switch_get_active (GTK_SWITCH(sno_switch)); app_data->disable_notifications = gtk_switch_get_active (GTK_SWITCH(dn_switch)); app_data->search_column = (gint)g_ascii_strtoll (gtk_combo_box_get_active_id (GTK_COMBO_BOX(sc_cb)), NULL, 10); - app_data->auto_lock = gtk_switch_get_active (GTK_SWITCH(al_switch)); - app_data->inactivity_timeout = (gint)g_ascii_strtoll (gtk_combo_box_get_active_id (GTK_COMBO_BOX(inactivity_cb)), NULL, 10); + app_data->auto_lock = gtk_switch_get_active (GTK_SWITCH(settings_data->al_switch)); + app_data->inactivity_timeout = (gint)g_ascii_strtoll (gtk_combo_box_get_active_id (GTK_COMBO_BOX(settings_data->inactivity_cb)), NULL, 10); app_data->use_dark_theme = gtk_switch_get_active (GTK_SWITCH(dt_switch)); - app_data->disable_secret_service = gtk_switch_get_active (GTK_SWITCH(dss_switch)); + app_data->use_secret_service = gtk_switch_get_active (GTK_SWITCH(settings_data->dss_switch)); g_key_file_set_boolean (kf, "config", "show_next_otp", app_data->show_next_otp); g_key_file_set_boolean (kf, "config", "notifications", app_data->disable_notifications); g_key_file_set_integer (kf, "config", "search_column", app_data->search_column); g_key_file_set_boolean (kf, "config", "auto_lock", app_data->auto_lock); g_key_file_set_integer (kf, "config", "inactivity_timeout", app_data->inactivity_timeout); g_key_file_set_boolean (kf, "config", "dark_theme", app_data->use_dark_theme); - g_key_file_set_boolean (kf, "config", "disable_secret_service", app_data->disable_secret_service); - if (old_ss_value == FALSE && app_data->disable_secret_service == TRUE) { + g_key_file_set_boolean (kf, "config", "use_secret_service", app_data->use_secret_service); + if (old_ss_value == TRUE && app_data->use_secret_service == FALSE) { // secret service was just disabled, so we have to clear the password from the keyring secret_password_clear (OTPCLIENT_SCHEMA, NULL, on_password_cleared, NULL, "string", "main_pwd", NULL); } @@ -99,6 +136,7 @@ g_free (cfg_file_path); g_key_file_free (kf); + g_free (settings_data); gtk_widget_destroy (dialog); @@ -111,4 +149,109 @@ gpointer user_data) { settings_dialog_cb (NULL, NULL, user_data); +} + + +static void +handle_al_ss (AppData *app_data, + GtkWidget *al_switch, + GtkWidget *inactivity_cb, + GtkWidget *dss_switch) +{ + GKeyFile *kf = get_kf_ptr (); + if (app_data->use_secret_service == TRUE) { + // secret service is enabled, so we need to disable auto-lock + app_data->auto_lock = FALSE; + app_data->inactivity_timeout = 0; + gtk_widget_set_sensitive (al_switch, FALSE); + gtk_widget_set_sensitive (inactivity_cb, FALSE); + } else { + if (app_data->auto_lock == TRUE || app_data->inactivity_timeout > 0) { + // if secret service is disabled AND (auto-lock is enabled OR timeout is enabled), we need to disable secret service + app_data->use_secret_service = FALSE; + gtk_widget_set_sensitive (dss_switch, FALSE); + } + } + if (kf != NULL) { + // Until the migration is done for all users, we need to manually update the settings. + // This code block can be removed once all distros have upgrade to, at least, version 3.1.4. + g_key_file_set_boolean (kf, "config", "auto_lock", app_data->auto_lock); + g_key_file_set_boolean (kf, "config", "use_secret_service", app_data->use_secret_service); + g_key_file_set_integer (kf, "config", "inactivity_timeout", app_data->inactivity_timeout); + gchar *cfg_file_path; +#ifndef USE_FLATPAK_APP_FOLDER + cfg_file_path = g_build_filename (g_get_user_config_dir (), "otpclient.cfg", NULL); +#else + cfg_file_path = g_build_filename (g_get_user_data_dir (), "otpclient.cfg", NULL); +#endif + if (!g_key_file_save_to_file (kf, cfg_file_path, NULL)) { + g_printerr ("%s\n", _("Error while saving the config file.")); + } + g_key_file_free (kf); + } +} + + +static gboolean +handle_secretservice_switch (GtkSwitch *sw, + gboolean state, + gpointer user_data) +{ + /* SecretService is disabled (TRUE), and we disable both autolock (FALSE) AND autolock timeout (0): + * - secret_service_switch_id must be set to sensitive + */ + SettingsData *settings_data = (SettingsData *)user_data; + settings_data->app_data->auto_lock = state; + if (state == FALSE && settings_data->app_data->inactivity_timeout == 0) { + gtk_widget_set_sensitive (settings_data->dss_switch, TRUE); + } else { + gtk_widget_set_sensitive (settings_data->dss_switch, FALSE); + } + gtk_switch_set_state (GTK_SWITCH(sw), state); + + return TRUE; +} + + +static void +handle_secretservice_combobox (GtkComboBox *cb, + gpointer user_data) +{ + /* SecretService is disabled (TRUE), and we disable both autolock (FALSE) AND autolock timeout (0): + * - secret_service_switch_id must be set to sensitive + */ + SettingsData *settings_data = (SettingsData *)user_data; + settings_data->app_data->inactivity_timeout = (gint)g_ascii_strtoll (gtk_combo_box_get_active_id (GTK_COMBO_BOX(cb)), NULL, 10); + if (settings_data->app_data->inactivity_timeout == 0 && settings_data->app_data->auto_lock == FALSE) { + gtk_widget_set_sensitive (settings_data->dss_switch, TRUE); + } else { + gtk_widget_set_sensitive (settings_data->dss_switch, FALSE); + } +} + + +static gboolean +handle_autolock (GtkSwitch *sw __attribute__((unused)), + gboolean state, + gpointer user_data) +{ + /* SecretService is enabled, and we disable it (TRUE -> FALSE): + * - lock_btn_id, autolock_switch_id and autolock_inactive_cb_id must be set to sensitive + * - add entry signal ctrl-l + */ + SettingsData *settings_data = (SettingsData *)user_data; + if (state == FALSE) { + gtk_widget_set_sensitive (GTK_WIDGET(gtk_builder_get_object (settings_data->app_data->builder, "lock_btn_id")), TRUE); + gtk_widget_set_sensitive (settings_data->al_switch, TRUE); + gtk_widget_set_sensitive (settings_data->inactivity_cb, TRUE); + gtk_binding_entry_add_signal (gtk_binding_set_by_class (GTK_APPLICATION_WINDOW_GET_CLASS(settings_data->app_data->main_window)), GDK_KEY_l, GDK_CONTROL_MASK, "lock-app", 0); + } else { + gtk_widget_set_sensitive (GTK_WIDGET(gtk_builder_get_object (settings_data->app_data->builder, "lock_btn_id")), FALSE); + gtk_widget_set_sensitive (settings_data->al_switch, FALSE); + gtk_widget_set_sensitive (settings_data->inactivity_cb, FALSE); + gtk_binding_entry_remove (gtk_binding_set_by_class (GTK_APPLICATION_WINDOW_GET_CLASS(settings_data->app_data->main_window)), GDK_KEY_l, GDK_CONTROL_MASK); + } + gtk_switch_set_state (GTK_SWITCH(sw), state); + + return TRUE; } \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/setup-signals-shortcuts.c new/OTPClient-3.1.4/src/setup-signals-shortcuts.c --- old/OTPClient-3.1.3/src/setup-signals-shortcuts.c 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/setup-signals-shortcuts.c 2023-02-10 10:23:43.000000000 +0100 @@ -26,7 +26,10 @@ gtk_binding_entry_add_signal(mw_binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "toggle-reorder-button", 0); gtk_binding_entry_add_signal (mw_binding_set, GDK_KEY_d, GDK_CONTROL_MASK, "toggle-delete-button", 0); - gtk_binding_entry_add_signal (mw_binding_set, GDK_KEY_l, GDK_CONTROL_MASK, "lock-app", 0); + if (app_data->auto_lock == TRUE || app_data->inactivity_timeout > 0) { + // auto-lock is enabled, so secret service is disabled, therefore we allow the shortcut + gtk_binding_entry_add_signal (mw_binding_set, GDK_KEY_l, GDK_CONTROL_MASK, "lock-app", 0); + } gtk_binding_entry_add_signal (mw_binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "change-db", 0); gtk_binding_entry_add_signal (mw_binding_set, GDK_KEY_o, GDK_CONTROL_MASK, "change-pwd", 0); gtk_binding_entry_add_signal (mw_binding_set, GDK_KEY_s, GDK_CONTROL_MASK, "show-settings", 0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/OTPClient-3.1.3/src/ui/otpclient.ui new/OTPClient-3.1.4/src/ui/otpclient.ui --- old/OTPClient-3.1.3/src/ui/otpclient.ui 2023-01-13 11:32:56.000000000 +0100 +++ new/OTPClient-3.1.4/src/ui/otpclient.ui 2023-02-10 10:23:43.000000000 +0100 @@ -1900,7 +1900,7 @@ <object class="GtkLabel"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="label" translatable="yes">Disable secret service</property> + <property name="label" translatable="yes">Enable secret service</property> </object> <packing> <property name="left-attach">0</property> @@ -1908,7 +1908,7 @@ </packing> </child> <child> - <object class="GtkSwitch" id="disable_secret_service_switch_id"> + <object class="GtkSwitch" id="secret_service_switch_id"> <property name="visible">True</property> <property name="can-focus">True</property> <property name="halign">center</property>