diff options
author | Antenore Gatta (tmow) <antenore@simbiosi.org> | 2022-01-04 17:54:28 +0300 |
---|---|---|
committer | Antenore Gatta (tmow) <antenore@simbiosi.org> | 2022-01-04 17:54:28 +0300 |
commit | e5f27de6ad23f85dd1cfcd0ec560b2c54234c58a (patch) | |
tree | 35306363a51e74f5b198b0f47d9027e90838b4c9 /src | |
parent | 310e6f98e789fd1b2381d5b2c1e0c1884f04598b (diff) |
Remmina Hardening and Compliance
This Patch is meant to:
- Enhance the use of the Primary Password
- Replace the internal password hashing algorithm
- Add an auditing log.
This first commit adds some new settings in the Remmina preferences editor,
and enhance the Primary Password functionalities.
It's now possible to chose to lock Preferences (default), connections and
edit actions (separately).
Signed-off-by: Antenore Gatta (tmow) <antenore@simbiosi.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/remmina_exec.c | 7 | ||||
-rw-r--r-- | src/remmina_main.c | 24 | ||||
-rw-r--r-- | src/remmina_pref.c | 39 | ||||
-rw-r--r-- | src/remmina_pref.h | 4 | ||||
-rw-r--r-- | src/remmina_pref_dialog.c | 22 | ||||
-rw-r--r-- | src/remmina_pref_dialog.h | 4 | ||||
-rw-r--r-- | src/remmina_stats.c | 20 | ||||
-rw-r--r-- | src/remmina_unlock.c | 6 |
8 files changed, 89 insertions, 37 deletions
diff --git a/src/remmina_exec.c b/src/remmina_exec.c index 6b2d1ede5..bed8839f0 100644 --- a/src/remmina_exec.c +++ b/src/remmina_exec.c @@ -410,6 +410,8 @@ void remmina_exec_command(RemminaCommandType command, const gchar* data) break; case REMMINA_COMMAND_NEW: + if (remmina_pref_get_boolean("lock_edit") && remmina_unlock_new(mainwindow) == 0) + break; s1 = (data ? strchr(data, ',') : NULL); if (s1) { s1 = g_strdup(data); @@ -424,14 +426,19 @@ void remmina_exec_command(RemminaCommandType command, const gchar* data) break; case REMMINA_COMMAND_CONNECT: + REMMINA_DEBUG ("Initiating connection"); /** @todo This should be a G_OPTION_ARG_FILENAME_ARRAY (^aay) so that * we can implement multi profile connection: * https://gitlab.com/Remmina/Remmina/issues/915 */ + if (remmina_pref_get_boolean("lock_connect") && remmina_unlock_new(mainwindow) == 0) + break; remmina_exec_connect(data); break; case REMMINA_COMMAND_EDIT: + if (remmina_pref_get_boolean("lock_edit") && remmina_unlock_new(mainwindow) == 0) + break; widget = remmina_file_editor_new_from_filename(data); if (widget) gtk_widget_show(widget); diff --git a/src/remmina_main.c b/src/remmina_main.c index caf61b990..15dfc35f3 100644 --- a/src/remmina_main.c +++ b/src/remmina_main.c @@ -731,6 +731,9 @@ void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant * if (remminafile == NULL) return; + if (remmina_pref_get_boolean("lock_connect") && + remmina_unlock_new(remminamain->window) == 0) + return; remmina_file_touch(remminafile); rcw_open_from_filename(remminamain->priv->selected_filename); @@ -770,6 +773,11 @@ void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant username = domain = group = ""; remminafile = NULL; + + if (remmina_pref_get_boolean("lock_edit") && + remmina_unlock_new(remminamain->window) == 0) + return; + if (remminamain->priv->selected_filename) { remminafile = remmina_file_load(remminamain->priv->selected_filename); if (remminafile != NULL) { @@ -779,9 +787,6 @@ void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant } } - if (remmina_unlock_new(remminamain->window) == 0) - return; - remmina_mpchange_schedule(TRUE, group, domain, username, ""); if (remminafile != NULL) @@ -793,7 +798,8 @@ void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *para TRACE_CALL(__func__); GtkWidget *widget; - if (remmina_unlock_new(remminamain->window) == 0) + if (remmina_pref_get_boolean("lock_edit") && + remmina_unlock_new(remminamain->window) == 0) return; widget = remmina_file_editor_new(); @@ -854,6 +860,10 @@ void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *par if (!remminamain->priv->selected_filename) return; + if (remmina_pref_get_boolean("lock_edit") && + remmina_unlock_new(remminamain->window) == 0) + return; + widget = remmina_file_editor_new_copy(remminamain->priv->selected_filename); if (widget) { g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(remmina_main_file_editor_destroy), remminamain); @@ -870,7 +880,8 @@ void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *par TRACE_CALL(__func__); GtkWidget *widget; - if (remmina_unlock_new(remminamain->window) == 0) + if (remmina_pref_get_boolean("lock_edit") && + remmina_unlock_new(remminamain->window) == 0) return; if (!remminamain->priv->selected_filename) @@ -895,7 +906,8 @@ void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *p if (!remminamain->priv->selected_filename) return; - if (remmina_unlock_new(remminamain->window) == 0) + if (remmina_pref_get_boolean("lock_edit") && + remmina_unlock_new(remminamain->window) == 0) return; dialog = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, diff --git a/src/remmina_pref.c b/src/remmina_pref.c index 5d1e474d3..efe637d75 100644 --- a/src/remmina_pref.c +++ b/src/remmina_pref.c @@ -51,6 +51,7 @@ #include "remmina_public.h" #include "remmina_string_array.h" #include "remmina_pref.h" +#include "remmina_log.h" #include "remmina/remmina_trace_calls.h" const gchar *default_resolutions = "640x480,800x600,1024x768,1152x864,1280x960,1400x1050"; @@ -282,10 +283,12 @@ void remmina_pref_init(void) else remmina_pref.save_view_mode = TRUE; - if (g_key_file_has_key(gkeyfile, "remmina_pref", "use_master_password", NULL)) - remmina_pref.use_master_password = g_key_file_get_boolean(gkeyfile, "remmina_pref", "use_master_password", NULL); + if (g_key_file_has_key(gkeyfile, "remmina_pref", "use_master_password", NULL)) { + remmina_pref.use_primary_password = g_key_file_get_boolean(gkeyfile, "remmina_pref", "use_master_password", NULL); + } else if (g_key_file_has_key(gkeyfile, "remmina_pref", "use_primary_password", NULL)) + remmina_pref.use_primary_password = g_key_file_get_boolean(gkeyfile, "remmina_pref", "use_primary_password", NULL); else - remmina_pref.use_master_password = FALSE; + remmina_pref.use_primary_password = FALSE; if (g_key_file_has_key(gkeyfile, "remmina_pref", "unlock_timeout", NULL)) remmina_pref.unlock_timeout = g_key_file_get_integer(gkeyfile, "remmina_pref", "unlock_timeout", NULL); @@ -297,6 +300,16 @@ void remmina_pref_init(void) else remmina_pref.unlock_password = g_strdup(""); + if (g_key_file_has_key(gkeyfile, "remmina_pref", "lock_connect", NULL)) + remmina_pref.lock_connect = g_key_file_get_boolean(gkeyfile, "remmina_pref", "lock_connect", NULL); + else + remmina_pref.lock_connect = FALSE; + + if (g_key_file_has_key(gkeyfile, "remmina_pref", "lock_edit", NULL)) + remmina_pref.lock_edit = g_key_file_get_boolean(gkeyfile, "remmina_pref", "lock_edit", NULL); + else + remmina_pref.lock_edit = FALSE; + if (g_key_file_has_key(gkeyfile, "remmina_pref", "trust_all", NULL)) remmina_pref.trust_all = g_key_file_get_boolean(gkeyfile, "remmina_pref", "trust_all", NULL); else @@ -693,10 +706,10 @@ void remmina_pref_init(void) if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_last_get", NULL)) { remmina_pref.periodic_rmnews_last_get = g_key_file_get_int64(gkeyfile, "remmina_news", "periodic_rmnews_last_get", NULL); - g_debug("(%s) - periodic_rmnews_last_get set to %ld", __func__, remmina_pref.periodic_rmnews_last_get); + REMMINA_DEBUG ("periodic_rmnews_last_get set to %ld", remmina_pref.periodic_rmnews_last_get); } else { remmina_pref.periodic_rmnews_last_get = 0; - g_debug("(%s) - periodic_rmnews_last_get set to 0", __func__); + REMMINA_DEBUG ("periodic_rmnews_last_get set to 0"); } if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_get_count", NULL)) @@ -765,14 +778,22 @@ gboolean remmina_pref_save(void) g_key_file_set_string(gkeyfile, "remmina_pref", "screenshot_name", remmina_pref.screenshot_name); g_key_file_set_boolean(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", remmina_pref.deny_screenshot_clipboard); g_key_file_set_boolean(gkeyfile, "remmina_pref", "save_view_mode", remmina_pref.save_view_mode); + if (g_key_file_remove_key (gkeyfile, "remmina_pref", "use_master_password", NULL)) + REMMINA_DEBUG("use_master_password removed..."); + else + REMMINA_INFO("use_master_password already migrated"); #if SODIUM_VERSION_INT >= 90200 - g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_master_password", remmina_pref.use_master_password); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_primary_password", remmina_pref.use_primary_password); g_key_file_set_integer(gkeyfile, "remmina_pref", "unlock_timeout", remmina_pref.unlock_timeout); g_key_file_set_string(gkeyfile, "remmina_pref", "unlock_password", remmina_pref.unlock_password); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "lock_connect", remmina_pref.lock_connect); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "lock_edit", remmina_pref.lock_edit); #else - g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_master_password", FALSE); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_primary_password", FALSE); g_key_file_set_integer(gkeyfile, "remmina_pref", "unlock_timeout", 0); g_key_file_set_string(gkeyfile, "remmina_pref", "unlock_password", g_strdup("")); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "lock_connect", FALSE); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "lock_edit", FALSE); #endif g_key_file_set_boolean(gkeyfile, "remmina_pref", "trust_all", remmina_pref.trust_all); g_key_file_set_integer(gkeyfile, "remmina_pref", "floating_toolbar_placement", remmina_pref.floating_toolbar_placement); @@ -972,10 +993,10 @@ void remmina_pref_clear_recent(void) guint *remmina_pref_keymap_get_table(const gchar *keymap) { TRACE_CALL(__func__); - + if (!keymap || keymap[0] == '\0') return NULL; - + return (guint *)g_hash_table_lookup(remmina_keymap_table, keymap); } diff --git a/src/remmina_pref.h b/src/remmina_pref.h index 4fe45757f..6e5fc9ed7 100644 --- a/src/remmina_pref.h +++ b/src/remmina_pref.h @@ -167,10 +167,12 @@ typedef struct _RemminaPref { guint shortcutkey_disconnect; guint shortcutkey_toolbar; /* In RemminaPrefDialog security tab */ - gboolean use_master_password; + gboolean use_primary_password; const gchar * unlock_password; const gchar * unlock_repassword; gint unlock_timeout; + gboolean lock_connect; + gboolean lock_edit; gboolean trust_all; /* In RemminaPrefDialog terminal tab */ gchar * vte_font; diff --git a/src/remmina_pref_dialog.c b/src/remmina_pref_dialog.c index 598d1a0ac..6d9053cff 100644 --- a/src/remmina_pref_dialog.c +++ b/src/remmina_pref_dialog.c @@ -233,12 +233,14 @@ void remmina_pref_on_dialog_destroy(GtkWidget *widget, gpointer user_data) remmina_pref.screenshot_name = gtk_entry_get_text(remmina_pref_dialog->entry_options_screenshot_name); remmina_pref.deny_screenshot_clipboard = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_options_deny_screenshot_clipboard)); remmina_pref.save_view_mode = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_options_remember_last_view_mode)); - remmina_pref.use_master_password = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_security_use_master_password)); + remmina_pref.use_primary_password = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_security_use_primary_password)); #if SODIUM_VERSION_INT >= 90200 remmina_pref.unlock_repassword = gtk_entry_get_text(remmina_pref_dialog->unlock_repassword); if (gtk_entry_get_text_length(remmina_pref_dialog->unlock_repassword) != 0) remmina_pref.unlock_password = remmina_sodium_pwhash_str(gtk_entry_get_text(remmina_pref_dialog->unlock_password)); #endif + remmina_pref.lock_connect = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_security_lock_connect)); + remmina_pref.lock_edit = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_security_lock_edit)); remmina_pref.trust_all = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_security_trust_all)); remmina_pref.screenshot_path = gtk_file_chooser_get_filename(remmina_pref_dialog->filechooserbutton_options_screenshots_path); remmina_pref.fullscreen_on_auto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_appearance_fullscreen_on_auto)); @@ -466,22 +468,26 @@ static void remmina_pref_dialog_init(void) gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_options_remember_last_view_mode), remmina_pref.save_view_mode); #if SODIUM_VERSION_INT >= 90200 - gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_use_master_password), remmina_pref.use_master_password); + gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_use_primary_password), remmina_pref.use_primary_password); if (remmina_pref.unlock_password != NULL) gtk_entry_set_text(remmina_pref_dialog->unlock_password, remmina_pref.unlock_password); else gtk_entry_set_text(remmina_pref_dialog->unlock_password, ""); - gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->switch_security_use_master_password), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->switch_security_use_primary_password), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->unlock_password), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->unlock_repassword), TRUE); + gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_lock_connect), remmina_pref.lock_connect); + gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_lock_edit), remmina_pref.lock_edit); gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->unlock_timeout), TRUE); #else - gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_use_master_password), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->switch_security_use_master_password), FALSE); + gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_use_primary_password), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->switch_security_use_primary_password), FALSE); // TRANSLATORS: Do not translate libsodium, is the name of a library - gtk_widget_set_tooltip_text(GTK_WIDGET(remmina_pref_dialog->switch_security_use_master_password), _("libsodium >= 1.9.0 is required to use master password")); + gtk_widget_set_tooltip_text(GTK_WIDGET(remmina_pref_dialog->switch_security_use_primary_password), _("libsodium >= 1.9.0 is required to use Primary Password")); gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->unlock_password), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->unlock_repassword), FALSE); + gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_lock_connect), FALSE); + gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_lock_edit), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(remmina_pref_dialog->unlock_timeout), FALSE); #endif gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_security_trust_all), remmina_pref.trust_all); @@ -706,9 +712,11 @@ GtkWidget *remmina_pref_dialog_new(gint default_tab, GtkWindow *parent) remmina_pref_dialog->entry_options_screenshot_name = GTK_ENTRY(GET_OBJECT("entry_options_screenshot_name")); remmina_pref_dialog->switch_options_deny_screenshot_clipboard = GTK_SWITCH(GET_OBJECT("switch_options_deny_screenshot_clipboard")); remmina_pref_dialog->switch_options_remember_last_view_mode = GTK_SWITCH(GET_OBJECT("switch_options_remember_last_view_mode")); - remmina_pref_dialog->switch_security_use_master_password = GTK_SWITCH(GET_OBJECT("switch_security_use_master_password")); + remmina_pref_dialog->switch_security_use_primary_password = GTK_SWITCH(GET_OBJECT("switch_security_use_primary_password")); remmina_pref_dialog->unlock_password = GTK_ENTRY(GET_OBJECT("unlock_password")); remmina_pref_dialog->unlock_repassword = GTK_ENTRY(GET_OBJECT("unlock_repassword")); + remmina_pref_dialog->switch_security_lock_connect = GTK_SWITCH(GET_OBJECT("switch_security_lock_connect")); + remmina_pref_dialog->switch_security_lock_edit = GTK_SWITCH(GET_OBJECT("switch_security_lock_edit")); remmina_pref_dialog->switch_security_trust_all = GTK_SWITCH(GET_OBJECT("switch_security_trust_all")); remmina_pref_dialog->checkbutton_options_save_settings = GTK_CHECK_BUTTON(GET_OBJECT("checkbutton_options_save_settings")); remmina_pref_dialog->checkbutton_appearance_fullscreen_on_auto = GTK_CHECK_BUTTON(GET_OBJECT("checkbutton_appearance_fullscreen_on_auto")); diff --git a/src/remmina_pref_dialog.h b/src/remmina_pref_dialog.h index 7815f11f0..97163343e 100644 --- a/src/remmina_pref_dialog.h +++ b/src/remmina_pref_dialog.h @@ -56,10 +56,12 @@ typedef struct _RemminaPrefDialog { GtkSwitch * switch_appearance_grab_color; GtkSwitch * switch_options_deny_screenshot_clipboard; GtkSwitch * switch_options_remember_last_view_mode; - GtkSwitch * switch_security_use_master_password; + GtkSwitch * switch_security_use_primary_password; GtkEntry * unlock_timeout; GtkEntry * unlock_password; GtkEntry * unlock_repassword; + GtkSwitch * switch_security_lock_connect; + GtkSwitch * switch_security_lock_edit; GtkSwitch * switch_security_trust_all; GtkCheckButton * checkbutton_options_save_settings; GtkCheckButton * checkbutton_appearance_fullscreen_on_auto; diff --git a/src/remmina_stats.c b/src/remmina_stats.c index e4e93d401..bd5fb0464 100644 --- a/src/remmina_stats.c +++ b/src/remmina_stats.c @@ -114,8 +114,8 @@ * "ACTIVESECRETPLUGIN": { * "plugin_name": "kwallet" * } - * "HASMASTERPASSWORD": { - * "master_password_status": "OFF" + * "HASPRIMARYPASSWORD": { + * "primary_password_status": "OFF" * } * * } @@ -739,12 +739,12 @@ JsonNode *remmina_stats_get_secret_plugin() } /** - * Add a JSON member HASMASTERPASSWORD which shows the status of the master password. + * Add a JSON member HASPRIMARYPASSWORD which shows the status of the master password. * - * @return a JSON Node structure containing the status of the master password + * @return a JSON Node structure containing the status of the primary password * */ -JsonNode *remmina_stats_get_master_password_status() +JsonNode *remmina_stats_get_primary_password_status() { TRACE_CALL(__func__); @@ -754,8 +754,8 @@ JsonNode *remmina_stats_get_master_password_status() b = json_builder_new(); json_builder_begin_object(b); - json_builder_set_member_name(b, "master_password_status"); - if (remmina_pref_get_boolean("use_master_password")) { + json_builder_set_member_name(b, "primary_password_status"); + if (remmina_pref_get_boolean("use_primary_password")) { json_builder_add_string_value(b, "ON"); } else { json_builder_add_string_value(b, "OFF"); @@ -771,7 +771,7 @@ JsonNode *remmina_stats_get_master_password_status() /** * Add a json member KIOSK which shows the status of the kiosk. * - * @return a JSON Node structure containing the status of the master password + * @return a JSON Node structure containing the status of the primary password * */ JsonNode *remmina_stats_get_kiosk_mode() @@ -854,8 +854,8 @@ JsonNode *remmina_stats_get_all() json_builder_set_member_name(b, "ACTIVESECRETPLUGIN"); json_builder_add_value(b, n); - n = remmina_stats_get_master_password_status(); - json_builder_set_member_name(b, "HASMASTERPASSWORD"); + n = remmina_stats_get_primary_password_status(); + json_builder_set_member_name(b, "HASPRIMARYPASSWORD"); json_builder_add_value(b, n); n = remmina_stats_get_kiosk_mode(); diff --git a/src/remmina_unlock.c b/src/remmina_unlock.c index 21114a9fb..112ad70a3 100644 --- a/src/remmina_unlock.c +++ b/src/remmina_unlock.c @@ -58,7 +58,7 @@ static void remmina_unlock_timer_init() TRACE_CALL(__func__); timer = g_timer_new(); - g_info("Unlock Master Password timer initialized"); + g_info("Unlock Primary Password timer initialized"); } static void remmina_unlock_timer_reset(gpointer user_data) @@ -66,7 +66,7 @@ static void remmina_unlock_timer_reset(gpointer user_data) TRACE_CALL(__func__); g_timer_reset(timer); - g_info("Unlock Master Password timer reset"); + g_info("Unlock Primary Password timer reset"); } void remmina_unlock_timer_destroy() @@ -164,7 +164,7 @@ gint remmina_unlock_new(GtkWindow *parent) /* Connect signals */ gtk_builder_connect_signals(remmina_unlock_dialog->builder, NULL); - if (remmina_pref_get_boolean("use_master_password") + if (remmina_pref_get_boolean("use_primary_password") && (g_strcmp0(remmina_pref_get_value("unlock_password"), "") != 0) && lock != 0) gtk_dialog_run(remmina_unlock_dialog->dialog); |