diff --git a/plugins/secret/src/glibsecret_plugin.c b/plugins/secret/src/glibsecret_plugin.c index c28ead8970..9ba1b07afa 100644 --- a/plugins/secret/src/glibsecret_plugin.c +++ b/plugins/secret/src/glibsecret_plugin.c @@ -56,7 +56,20 @@ static SecretService* secretservice; static SecretCollection* defaultcollection; #endif -static void remmina_plugin_glibsecret_unlock_secret_service() + +gboolean remmina_plugin_glibsecret_is_service_available() +{ +#ifdef LIBSECRET_VERSION_0_18 + if (secretservice && defaultcollection) + return TRUE; + else + return FALSE; +#else + return FALSE; +#endif +} + +static void remmina_plugin_glibsecret_unlock_secret_service() { TRACE_CALL(__func__); @@ -87,8 +100,6 @@ void remmina_plugin_glibsecret_store_password(RemminaFile *remminafile, const gc const gchar *path; gchar *s; - remmina_plugin_glibsecret_unlock_secret_service(); - path = remmina_plugin_service->file_get_path(remminafile); s = g_strdup_printf("Remmina: %s - %s", remmina_plugin_service->file_get_string(remminafile, "name"), key); secret_password_store_sync(&remmina_file_secret_schema, SECRET_COLLECTION_DEFAULT, s, password, @@ -111,8 +122,6 @@ remmina_plugin_glibsecret_get_password(RemminaFile *remminafile, const gchar *ke gchar *password; gchar *p; - remmina_plugin_glibsecret_unlock_secret_service(); - path = remmina_plugin_service->file_get_path(remminafile); password = secret_password_lookup_sync(&remmina_file_secret_schema, NULL, &r, "filename", path, "key", key, NULL); if (r == NULL) { @@ -132,8 +141,6 @@ void remmina_plugin_glibsecret_delete_password(RemminaFile *remminafile, const g GError *r = NULL; const gchar *path; - remmina_plugin_glibsecret_unlock_secret_service(); - path = remmina_plugin_service->file_get_path(remminafile); secret_password_clear_sync(&remmina_file_secret_schema, NULL, &r, "filename", path, "key", key, NULL); if (r == NULL) { @@ -144,9 +151,17 @@ void remmina_plugin_glibsecret_delete_password(RemminaFile *remminafile, const g } static RemminaSecretPlugin remmina_plugin_glibsecret = -{ REMMINA_PLUGIN_TYPE_SECRET, "glibsecret", "GNOME libsecret", NULL, VERSION, - - TRUE, remmina_plugin_glibsecret_store_password, remmina_plugin_glibsecret_get_password, remmina_plugin_glibsecret_delete_password }; +{ REMMINA_PLUGIN_TYPE_SECRET, + "glibsecret", + "GNOME libsecret", + NULL, + VERSION, + TRUE, + remmina_plugin_glibsecret_store_password, + remmina_plugin_glibsecret_get_password, + remmina_plugin_glibsecret_delete_password, + remmina_plugin_glibsecret_is_service_available +}; G_MODULE_EXPORT gboolean remmina_plugin_entry(RemminaPluginService *service) @@ -164,17 +179,27 @@ remmina_plugin_entry(RemminaPluginService *service) error = NULL; secretservice = secret_service_get_sync(SECRET_SERVICE_LOAD_COLLECTIONS, NULL, &error); if (error) { - remmina_plugin_service->log_printf("[glibsecret] unable to get secret service: %s\n", error->message); + g_print("[glibsecret] unable to get secret service: %s\n", error->message); + return FALSE; + } + if (secretservice == NULL) { + g_print("[glibsecret] unable to get secret service: Unknown error.\n"); return FALSE; } defaultcollection = secret_collection_for_alias_sync(secretservice, SECRET_COLLECTION_DEFAULT, SECRET_COLLECTION_NONE, NULL, &error); if (error) { - remmina_plugin_service->log_printf("[glibsecret] unable to get secret service default collection: %s\n", error->message); + g_print("[glibsecret] unable to get secret service default collection: %s\n", error->message); return FALSE; } -#endif + remmina_plugin_glibsecret_unlock_secret_service(); return TRUE; + +#else + g_print("Libsecret was too old during compilation, disabling secret service.\n"); + return FALSE; +#endif + } diff --git a/remmina/include/remmina/plugin.h b/remmina/include/remmina/plugin.h index 1b0aeb532d..874b4015d2 100644 --- a/remmina/include/remmina/plugin.h +++ b/remmina/include/remmina/plugin.h @@ -137,6 +137,7 @@ typedef struct _RemminaSecretPlugin { void (* store_password)(RemminaFile *remminafile, const gchar *key, const gchar *password); gchar* (*get_password)(RemminaFile * remminafile, const gchar * key); void (* delete_password)(RemminaFile *remminafile, const gchar *key); + gboolean (* is_service_available)(void); } RemminaSecretPlugin; /* Plugin Service is a struct containing a list of function pointers, diff --git a/remmina/src/remmina.c b/remmina/src/remmina.c index 9d2ec82645..7efc263e9d 100644 --- a/remmina/src/remmina.c +++ b/remmina/src/remmina.c @@ -201,6 +201,9 @@ static gint remmina_on_command_line(GApplication *app, GApplicationCommandLine * static void remmina_on_startup(GApplication *app) { TRACE_CALL(__func__); + + RemminaSecretPlugin *secret_plugin; + remmina_file_manager_init(); remmina_pref_init(); remmina_plugin_manager_init(); @@ -217,6 +220,18 @@ static void remmina_on_startup(GApplication *app) g_application_hold(app); remmina_stats_sender_schedule(); + + /* Check for secret plugin and service initialization and show some warnings on the console if + * there is something missing */ + secret_plugin = remmina_plugin_manager_get_secret_plugin(); + if (!secret_plugin) { + g_print("WARNING: Remmina is running without a secret plugin. Passwords will be saved in a less secure way.\n"); + } else { + if (!secret_plugin->is_service_available()) { + g_print("WARNING: Remmina is running with a secret plugin, but it cannot connect to a secret service.\n"); + } + } + } static gint remmina_on_local_cmdline(GApplication *app, GVariantDict *options, gpointer user_data) diff --git a/remmina/src/remmina_file.c b/remmina/src/remmina_file.c index d48c6591a6..ad12198554 100644 --- a/remmina/src/remmina_file.c +++ b/remmina/src/remmina_file.c @@ -216,6 +216,7 @@ remmina_file_load(const gchar *filename) gchar *s, *sec; RemminaProtocolPlugin* protocol_plugin; RemminaSecretPlugin *secret_plugin; + gboolean secret_service_available; int w, h; gkeyfile = g_key_file_new(); @@ -238,6 +239,8 @@ remmina_file_load(const gchar *filename) } secret_plugin = remmina_plugin_manager_get_secret_plugin(); + secret_service_available = secret_plugin->is_service_available(); + remminafile->filename = g_strdup(filename); keys = g_key_file_get_keys(gkeyfile, "remmina", NULL, NULL); if (keys) { @@ -246,7 +249,7 @@ remmina_file_load(const gchar *filename) if (is_encrypted_setting_by_name(key, protocol_plugin)) { s = g_key_file_get_string(gkeyfile, "remmina", key, NULL); if (g_strcmp0(s, ".") == 0) { - if (secret_plugin) { + if (secret_service_available) { sec = secret_plugin->get_password(remminafile, key); remmina_file_set_string(remminafile, key, sec); /* Annotate in spsettings that this value comes from secret_plugin */ @@ -406,6 +409,7 @@ void remmina_file_save(RemminaFile *remminafile) { TRACE_CALL(__func__); RemminaSecretPlugin *secret_plugin; + gboolean secret_service_available; RemminaProtocolPlugin* protocol_plugin; GHashTableIter iter; const gchar *key, *value; @@ -429,12 +433,13 @@ void remmina_file_save(RemminaFile *remminafile) } secret_plugin = remmina_plugin_manager_get_secret_plugin(); + secret_service_available = secret_plugin->is_service_available(); g_hash_table_iter_init(&iter, remminafile->settings); while (g_hash_table_iter_next(&iter, (gpointer*)&key, (gpointer*)&value)) { if (is_encrypted_setting_by_name(key, protocol_plugin)) { if (remminafile->filename && g_strcmp0(remminafile->filename, remmina_pref_file)) { - if (secret_plugin) { + if (secret_service_available) { if (value && value[0]) { if (g_strcmp0(value, ".") != 0) { secret_plugin->store_password(remminafile, key, value); diff --git a/remmina/src/remmina_main.c b/remmina/src/remmina_main.c index 9df3b99957..e73d165807 100644 --- a/remmina/src/remmina_main.c +++ b/remmina/src/remmina_main.c @@ -187,6 +187,59 @@ static void remmina_main_clear_selection_data(void) G_GNUC_END_IGNORE_DEPRECATIONS } +#ifdef SNAP_BUILD + +static void remmina_main_show_snap_welcome() +{ + GtkBuilder *dlgbuilder = NULL; + GtkWidget *dlg; + GtkWindow *parent; + int result; + static gboolean shown_once = FALSE; + gboolean need_snap_interface_connections = FALSE; + GtkWidget* dsa; + RemminaSecretPlugin *remmina_secret_plugin; + + if (shown_once) + return; + else + shown_once = TRUE; + + g_print("Remmina is compiled as a SNAP package.\n"); + remmina_secret_plugin = remmina_plugin_manager_get_secret_plugin(); + if (remmina_secret_plugin == NULL) { + g_print(" but we can't find the secret plugin inside the SNAP.\n"); + need_snap_interface_connections = TRUE; + } else { + if (!remmina_secret_plugin->is_service_available()) { + g_print(" but we can't access a secret service. Secret service or SNAP interface connection is missing.\n"); + need_snap_interface_connections = TRUE; + } + } + + if (need_snap_interface_connections && !remmina_pref.prevent_snap_welcome_message) { + dlgbuilder = remmina_public_gtk_builder_new_from_file("remmina_snap_info_dialog.glade"); + dsa = GTK_WIDGET(gtk_builder_get_object(dlgbuilder, "dontshowagain")); + if(dlgbuilder) { + parent = remmina_main_get_window(); + dlg = GTK_WIDGET(gtk_builder_get_object(dlgbuilder, "snapwarndlg")); + if (parent) + gtk_window_set_transient_for(GTK_WINDOW(dlg), parent); + gtk_builder_connect_signals(dlgbuilder,NULL); + result = gtk_dialog_run(GTK_DIALOG(dlg)); + if (result == 1) { + remmina_pref.prevent_snap_welcome_message = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dsa)); + remmina_pref_save(); + } + gtk_widget_destroy(dlg); + g_object_unref(dlgbuilder); + } + } + +} +#endif + + static gboolean remmina_main_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer user_data) { @@ -1102,6 +1155,11 @@ void remmina_main_on_show(GtkWidget *w, gpointer user_data) if (!remmina_pref.periodic_usage_stats_permission_asked) { gtk_widget_set_visible(GTK_WIDGET(remminamain->box_ustat), TRUE); } + +#ifdef SNAP_BUILD + remmina_main_show_snap_welcome(); +#endif + } void remmina_main_on_click_ustat_yes(GtkWidget *w, gpointer user_data) diff --git a/remmina/src/remmina_plugin_manager.c b/remmina/src/remmina_plugin_manager.c index 5c24a00995..b19c8efa96 100644 --- a/remmina/src/remmina_plugin_manager.c +++ b/remmina/src/remmina_plugin_manager.c @@ -103,9 +103,7 @@ static gboolean remmina_gtksocket_available() available = TRUE; } #endif - return available; - } diff --git a/remmina/src/remmina_pref.c b/remmina/src/remmina_pref.c index 9c1f35cc4b..d28dd2cf9b 100644 --- a/remmina/src/remmina_pref.c +++ b/remmina/src/remmina_pref.c @@ -255,6 +255,11 @@ void remmina_pref_init(void) else remmina_pref.floating_toolbar_placement = FLOATING_TOOLBAR_PLACEMENT_TOP; + if (g_key_file_has_key(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", NULL)) + remmina_pref.prevent_snap_welcome_message = g_key_file_get_boolean(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", NULL); + else + remmina_pref.prevent_snap_welcome_message = FALSE; + if (g_key_file_has_key(gkeyfile, "remmina_pref", "toolbar_placement", NULL)) remmina_pref.toolbar_placement = g_key_file_get_integer(gkeyfile, "remmina_pref", "toolbar_placement", NULL); else @@ -719,6 +724,7 @@ void remmina_pref_save(void) g_key_file_set_boolean(gkeyfile, "remmina_pref", "save_view_mode", remmina_pref.save_view_mode); g_key_file_set_integer(gkeyfile, "remmina_pref", "floating_toolbar_placement", remmina_pref.floating_toolbar_placement); g_key_file_set_integer(gkeyfile, "remmina_pref", "toolbar_placement", remmina_pref.toolbar_placement); + g_key_file_set_boolean(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", remmina_pref.prevent_snap_welcome_message); g_key_file_set_boolean(gkeyfile, "remmina_pref", "fullscreen_on_auto", remmina_pref.fullscreen_on_auto); g_key_file_set_boolean(gkeyfile, "remmina_pref", "always_show_tab", remmina_pref.always_show_tab); g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_connection_toolbar", remmina_pref.hide_connection_toolbar); diff --git a/remmina/src/remmina_pref.h b/remmina/src/remmina_pref.h index 7e33bbb704..763a5baffb 100644 --- a/remmina/src/remmina_pref.h +++ b/remmina/src/remmina_pref.h @@ -152,6 +152,7 @@ typedef struct _RemminaPref { gboolean toolbar_pin_down; gint floating_toolbar_placement; gint toolbar_placement; + gboolean prevent_snap_welcome_message; /* Crypto */ gchar *secret; diff --git a/remmina/ui/CMakeLists.txt b/remmina/ui/CMakeLists.txt index a56ac2a432..90b36d882f 100644 --- a/remmina/ui/CMakeLists.txt +++ b/remmina/ui/CMakeLists.txt @@ -39,3 +39,4 @@ install(FILES remmina_preferences.glade DESTINATION "${REMMINA_UIDIR}") install(FILES remmina_key_chooser.glade DESTINATION "${REMMINA_UIDIR}") install(FILES remmina_string_list.glade DESTINATION "${REMMINA_UIDIR}") install(FILES remmina_mpc.glade DESTINATION "${REMMINA_UIDIR}") +install(FILES remmina_snap_info_dialog.glade DESTINATION "${REMMINA_UIDIR}") diff --git a/remmina/ui/remmina_snap_info_dialog.glade b/remmina/ui/remmina_snap_info_dialog.glade new file mode 100644 index 0000000000..4c02a8cc80 --- /dev/null +++ b/remmina/ui/remmina_snap_info_dialog.glade @@ -0,0 +1,101 @@ + + + + + + False + False + dialog + + + False + 5 + 5 + vertical + 15 + + + False + end + + + gtk-ok + True + True + True + True + + + True + True + 1 + + + + + False + False + 0 + + + + + True + False + 9 + It seems that Remmina is running on your system as a SNAP package. To enable access to some important features, like passowrd saving in your keyring and RDP printer sharing, please open your software center and give the appropriate permissions to Remmina. As an alternative you can to enter the following commands in a terminal window: + True + start + 50 + 6 + + + True + True + 1 + + + + + True + False + start + 30 + 30 + sudo snap connect remmina:avahi-observe :avahi-observe +sudo snap connect remmina:cups-control :cups-control +sudo snap connect remmina:mount-observe :mount-observe +sudo snap connect remmina:password-manager-service :password-manager-service + True + + + + + + False + True + 2 + + + + + Do not show this message again + True + True + False + 0 + True + + + False + True + 3 + + + + + + button1 + + +