Remmina - The GTK+ Remote Desktop Client  v1.4.33
Remmina is a remote desktop client written in GTK+, aiming to be useful for system administrators and travellers, who need to work with lots of remote computers in front of either large monitors or tiny netbooks. Remmina supports multiple network protocols in an integrated and consistent user interface. Currently RDP, VNC, NX, XDMCP and SSH are supported.
remmina_plugin_manager.c
Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2010-2011 Vic Lee
4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  * In addition, as a special exception, the copyright holders give
23  * permission to link the code of portions of this program with the
24  * OpenSSL library under certain conditions as described in each
25  * individual source file, and distribute linked combinations
26  * including the two.
27  * You must obey the GNU General Public License in all respects
28  * for all of the code used other than OpenSSL. * If you modify
29  * file(s) with this exception, you may extend this exception to your
30  * version of the file(s), but you are not obligated to do so. * If you
31  * do not wish to do so, delete this exception statement from your
32  * version. * If you delete this exception statement from all source
33  * files in the program, then also delete it here.
34  *
35  */
36 
37 #include "config.h"
38 
39 
40 #include <gtk/gtk.h>
41 #include <glib/gi18n.h>
42 #include <gmodule.h>
43 #include <gio/gio.h>
44 #include <string.h>
45 #ifdef GDK_WINDOWING_X11
46 #include <gdk/gdkx.h>
47 #elif defined(GDK_WINDOWING_WAYLAND)
48 #include <gdk/gdkwayland.h>
49 #endif
50 #include "remmina_public.h"
51 #include "remmina_main.h"
52 #include "remmina_file_manager.h"
53 #include "remmina_pref.h"
55 #include "remmina_log.h"
56 #include "remmina_widget_pool.h"
57 #include "rcw.h"
58 #include "remmina_plugin_manager.h"
59 #include "remmina_plugin_native.h"
60 #include "remmina_public.h"
63 
64 static GPtrArray* remmina_plugin_table = NULL;
65 
66 /* A GHashTable of GHashTables where to store the names of the encrypted settings */
67 static GHashTable *encrypted_settings_cache = NULL;
68 
69 /* There can be only one secret plugin loaded */
71 
72 // TRANSLATORS: "Language Wrapper" is a wrapper for plugins written in other programmin languages (Python in this context)
73 static const gchar *remmina_plugin_type_name[] =
74 { N_("Protocol"), N_("Entry"), N_("File"), N_("Tool"), N_("Preference"), N_("Secret"), N_("Language Wrapper"), NULL };
75 
77 {
78  TRACE_CALL(__func__);
79  return g_strcmp0((*a)->name, (*b)->name);
80 }
81 
82 static void htdestroy(gpointer ht)
83 {
84  g_hash_table_unref(ht);
85 }
86 
87 static void init_settings_cache(RemminaPlugin *plugin)
88 {
89  TRACE_CALL(__func__);
90  RemminaProtocolPlugin *protocol_plugin;
91  const RemminaProtocolSetting* setting_iter;
92  GHashTable *pht;
93 
94  /* This code make a encrypted setting cache only for protocol plugins */
95 
96  if (plugin->type != REMMINA_PLUGIN_TYPE_PROTOCOL) {
97  return;
98  }
99 
100  if (encrypted_settings_cache == NULL)
101  encrypted_settings_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, htdestroy);
102 
103  if (!(pht = g_hash_table_lookup(encrypted_settings_cache, plugin->name))) {
104  pht = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
105  g_hash_table_insert(encrypted_settings_cache, g_strdup(plugin->name), pht);
106  }
107 
108  /* Some settings are encrypted "by name" */
109  /* g_hash_table_insert(pht, g_strdup("proxy_password"), (gpointer)TRUE); */
110 
111  g_hash_table_insert(pht, g_strdup("ssh_tunnel_password"), (gpointer)TRUE);
112  g_hash_table_insert(pht, g_strdup("ssh_tunnel_passphrase"), (gpointer)TRUE);
113 
114  /* ssh_password is no longer used starting from remmina 1.4.
115  * But we MUST mark it as encrypted setting, or the migration procedure will fail */
116  g_hash_table_insert(pht, g_strdup("ssh_password"), (gpointer)TRUE);
117 
118  /* Other settings are encrypted because of their type */
119  protocol_plugin = (RemminaProtocolPlugin *)plugin;
120  setting_iter = protocol_plugin->basic_settings;
121  if (setting_iter) {
122  while (setting_iter->type != REMMINA_PROTOCOL_SETTING_TYPE_END) {
123  if (setting_iter->type == REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD)
124  g_hash_table_insert(pht, g_strdup(remmina_plugin_manager_get_canonical_setting_name(setting_iter)), (gpointer)TRUE);
125  setting_iter++;
126  }
127  }
128  setting_iter = protocol_plugin->advanced_settings;
129  if (setting_iter) {
130  while (setting_iter->type != REMMINA_PROTOCOL_SETTING_TYPE_END) {
131  if (setting_iter->type == REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD)
132  g_hash_table_insert(pht, g_strdup(remmina_plugin_manager_get_canonical_setting_name(setting_iter)), (gpointer)TRUE);
133  setting_iter++;
134  }
135  }
136 
137 }
138 
140 {
141  TRACE_CALL(__func__);
142  if (plugin->type == REMMINA_PLUGIN_TYPE_SECRET) {
143  g_print("Remmina plugin %s (type=%s) has been registered, but is not yet initialized/activated. "
144  "The initialization order is %d.\n", plugin->name,
145  _(remmina_plugin_type_name[plugin->type]),
146  ((RemminaSecretPlugin*)plugin)->init_order);
147  }
148  init_settings_cache(plugin);
149 
150  g_ptr_array_add(remmina_plugin_table, plugin);
151  g_ptr_array_sort(remmina_plugin_table, (GCompareFunc)remmina_plugin_manager_compare_func);
152  return TRUE;
153 }
154 
156 {
157  GdkDisplayManager* dm;
158  GdkDisplay* d;
159  gboolean available;
160 
161  dm = gdk_display_manager_get();
162  d = gdk_display_manager_get_default_display(dm);
163  available = FALSE;
164 
165 #ifdef GDK_WINDOWING_X11
166  if (GDK_IS_X11_DISPLAY(d)) {
167  /* GtkSocket support is available only under X.Org */
168  available = TRUE;
169  }
170 #endif
171  return available;
172 }
173 
175 {
222 
224 
234 
243 
253 
255 
311 };
312 
313 const char *get_filename_ext(const char *filename) {
314  const char* last = strrchr(filename, '/');
315  const char *dot = strrchr(last, '.');
316  if(!dot || dot == filename) return "";
317  return dot + 1;
318 }
319 
320 static gint compare_secret_plugin_init_order(gconstpointer a, gconstpointer b)
321 {
322  RemminaSecretPlugin *sa, *sb;
323 
324  sa = (RemminaSecretPlugin*)a;
325  sb = (RemminaSecretPlugin*)b;
326 
327  if (sa->init_order > sb->init_order)
328  return 1;
329  else if (sa->init_order < sb->init_order)
330  return -1;
331  return 0;
332 }
333 
335 {
336  TRACE_CALL(__func__);
337  GDir *dir;
338  const gchar *name, *ptr;
339  gchar *fullpath;
340  RemminaPlugin *plugin;
342  int i, j;
343  GSList *secret_plugins;
344  GSList *sple;
345  GPtrArray *alternative_language_plugins;
346 
347  remmina_plugin_table = g_ptr_array_new();
348  alternative_language_plugins = g_ptr_array_new();
349 
350  if (!g_module_supported()) {
351  g_print("Dynamic loading of plugins is not supported on this platform!\n");
352  return;
353  }
354 
355  g_print("Load modules from %s\n", REMMINA_RUNTIME_PLUGINDIR);
356  dir = g_dir_open(REMMINA_RUNTIME_PLUGINDIR, 0, NULL);
357 
358  if (dir == NULL)
359  return;
360  while ((name = g_dir_read_name(dir)) != NULL) {
361  if ((ptr = strrchr(name, '.')) == NULL)
362  continue;
363  ptr++;
364  fullpath = g_strdup_printf(REMMINA_RUNTIME_PLUGINDIR "/%s", name);
366  g_ptr_array_add(alternative_language_plugins, g_strdup_printf(REMMINA_RUNTIME_PLUGINDIR "/%s", name));
367  g_free(fullpath);
368  continue;
369  }
370  remmina_plugin_native_load(&remmina_plugin_manager_service, fullpath);
371  g_free(fullpath);
372  }
373  g_dir_close(dir);
374 
375  while (alternative_language_plugins->len > 0) {
376  gboolean has_loaded = FALSE;
377  gchar* name = (gchar*)g_ptr_array_remove_index(alternative_language_plugins, 0);
378  const gchar* ext = get_filename_ext(name);
379 
380  for (j = 0; j < remmina_plugin_table->len && !has_loaded; j++) {
381  plugin = (RemminaPlugin*)g_ptr_array_index(remmina_plugin_table, j);
384  const gchar** supported_extention = wrapper_plugin->supported_extentions;
385  while (*supported_extention) {
386  if (g_str_equal(*supported_extention, ext)) {
387  has_loaded = wrapper_plugin->load(wrapper_plugin, name);
388  if (has_loaded) {
389  break;
390  }
391  }
392  supported_extention++;
393  }
394  if (has_loaded) break;
395  }
396  }
397 
398  if (!has_loaded) {
399  g_print("%s: Skip unsupported file type '%s'\n", name, ext);
400  }
401 
402  g_free(name);
403  }
404 
405  /* Now all secret plugins needs to initialize, following their init_order.
406  * The 1st plugin which will initialize correctly will be
407  * the default remmina_secret_plugin */
408 
409  if (remmina_secret_plugin)
410  g_print("Internal ERROR: remmina_secret_plugin must be null here\n");
411 
412  secret_plugins = NULL;
413  for (i = 0; i < remmina_plugin_table->len; i++) {
414  plugin = (RemminaPlugin*)g_ptr_array_index(remmina_plugin_table, i);
415  if (plugin->type == REMMINA_PLUGIN_TYPE_SECRET) {
416  secret_plugins = g_slist_insert_sorted(secret_plugins, (gpointer)plugin, compare_secret_plugin_init_order);
417  }
418  }
419 
420  sple = secret_plugins;
421  while(sple != NULL) {
422  sp = (RemminaSecretPlugin*)sple->data;
423  if (sp->init(sp)) {
424  g_print("The %s secret plugin has been initialized and it will be your default secret plugin\n",
425  sp->name);
426  remmina_secret_plugin = sp;
427  break;
428  }
429  sple = sple->next;
430  }
431 
432  g_slist_free(secret_plugins);
433  g_ptr_array_free(alternative_language_plugins, TRUE);
434 }
435 
436 gboolean remmina_plugin_manager_loader_supported(const char *filetype) {
437  TRACE_CALL(__func__);
438  return g_str_equal(G_MODULE_SUFFIX, filetype);
439 }
440 
442 {
443  TRACE_CALL(__func__);
444  RemminaPlugin *plugin;
445  gint i;
446 
447  for (i = 0; i < remmina_plugin_table->len; i++) {
448  plugin = (RemminaPlugin*)g_ptr_array_index(remmina_plugin_table, i);
449  if (plugin->type == type && g_strcmp0(plugin->name, name) == 0) {
450  return plugin;
451  }
452  }
453  return NULL;
454 }
455 
457 {
458  if (setting->name == NULL) {
460  return "server";
462  return "password";
464  return "resolution";
466  return "assistance_mode";
467  return "missing_setting_name_into_plugin_RemminaProtocolSetting";
468  }
469  return setting->name;
470 }
471 
473 {
474  TRACE_CALL(__func__);
475  RemminaPlugin *plugin;
476  gint i;
477 
478  for (i = 0; i < remmina_plugin_table->len; i++) {
479  plugin = (RemminaPlugin*)g_ptr_array_index(remmina_plugin_table, i);
480  if (plugin->type == type) {
481  func((gchar*)plugin->name, plugin, data);
482  }
483  }
484 }
485 
486 /* A copy of remmina_plugin_manager_show and remmina_plugin_manager_show_for_each
487  * This is because we want to print the list of plugins, and their versions, to the standard output
488  * with the remmina command line option --full-version instead of using the plugins widget
489  ** @todo Investigate to use only GListStore and than pass the elements to be shown to 2 separate
490  * functions
491  * WARNING: GListStore is supported only from GLib 2.44 */
493 {
494  TRACE_CALL(__func__);
495 
496  g_print("%-20s%-16s%-64s%-10s\n", plugin->name,
497  _(remmina_plugin_type_name[plugin->type]),
498  g_dgettext(plugin->domain, plugin->description),
499  plugin->version);
500  return FALSE;
501 }
502 
504 {
505  TRACE_CALL(__func__);
506  g_print("%-20s%-16s%-64s%-10s\n", "NAME", "TYPE", "DESCRIPTION", "PLUGIN AND LIBRARY VERSION");
507  g_ptr_array_foreach(remmina_plugin_table, (GFunc)remmina_plugin_manager_show_for_each_stdout, NULL);
508 }
509 
510 static gboolean remmina_plugin_manager_show_for_each(RemminaPlugin *plugin, GtkListStore *store)
511 {
512  TRACE_CALL(__func__);
513  GtkTreeIter iter;
514 
515  gtk_list_store_append(store, &iter);
516  gtk_list_store_set(store, &iter, 0, plugin->name, 1, _(remmina_plugin_type_name[plugin->type]), 2,
517  g_dgettext(plugin->domain, plugin->description), 3, plugin->version, -1);
518  return FALSE;
519 }
520 
521 void remmina_plugin_manager_show(GtkWindow *parent)
522 {
523  TRACE_CALL(__func__);
524  GtkWidget *dialog;
525  GtkWidget *scrolledwindow;
526  GtkWidget *tree;
527  GtkCellRenderer *renderer;
528  GtkTreeViewColumn *column;
529  GtkListStore *store;
530 
531  dialog = gtk_dialog_new_with_buttons(_("Plugins"), parent, GTK_DIALOG_MODAL, _("_OK"), GTK_RESPONSE_ACCEPT, NULL);
532  g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), dialog);
533  gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 350);
534 
535  scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
536  gtk_widget_show(scrolledwindow);
537  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
538  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), scrolledwindow, TRUE, TRUE, 0);
539 
540  tree = gtk_tree_view_new();
541  gtk_container_add(GTK_CONTAINER(scrolledwindow), tree);
542  gtk_widget_show(tree);
543 
544  store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
545  g_ptr_array_foreach(remmina_plugin_table, (GFunc)remmina_plugin_manager_show_for_each, store);
546  gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
547 
548  renderer = gtk_cell_renderer_text_new();
549  column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 0, NULL);
550  gtk_tree_view_column_set_resizable(column, TRUE);
551  gtk_tree_view_column_set_sort_column_id(column, 0);
552  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
553 
554  renderer = gtk_cell_renderer_text_new();
555  column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, "text", 1, NULL);
556  gtk_tree_view_column_set_resizable(column, TRUE);
557  gtk_tree_view_column_set_sort_column_id(column, 1);
558  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
559 
560  renderer = gtk_cell_renderer_text_new();
561  column = gtk_tree_view_column_new_with_attributes(_("Description"), renderer, "text", 2, NULL);
562  gtk_tree_view_column_set_resizable(column, TRUE);
563  gtk_tree_view_column_set_sort_column_id(column, 2);
564  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
565 
566  renderer = gtk_cell_renderer_text_new();
567  column = gtk_tree_view_column_new_with_attributes(_("Version"), renderer, "text", 3, NULL);
568  gtk_tree_view_column_set_resizable(column, TRUE);
569  gtk_tree_view_column_set_sort_column_id(column, 3);
570  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
571 
572  gtk_widget_show(dialog);
573 }
574 
576 {
577  TRACE_CALL(__func__);
578  RemminaFilePlugin *plugin;
579  gint i;
580 
581  for (i = 0; i < remmina_plugin_table->len; i++) {
582  plugin = (RemminaFilePlugin*)g_ptr_array_index(remmina_plugin_table, i);
583 
584  if (plugin->type != REMMINA_PLUGIN_TYPE_FILE)
585  continue;
586 
587  if (plugin->import_test_func(plugin, file)) {
588  return plugin;
589  }
590  }
591  return NULL;
592 }
593 
595 {
596  TRACE_CALL(__func__);
597  RemminaFilePlugin *plugin;
598  gint i;
599 
600  for (i = 0; i < remmina_plugin_table->len; i++) {
601  plugin = (RemminaFilePlugin*)g_ptr_array_index(remmina_plugin_table, i);
602  if (plugin->type != REMMINA_PLUGIN_TYPE_FILE)
603  continue;
604  if (plugin->export_test_func(plugin, remminafile)) {
605  return plugin;
606  }
607  }
608  return NULL;
609 }
610 
612 {
613  TRACE_CALL(__func__);
614  return remmina_secret_plugin;
615 }
616 
618 {
619  TRACE_CALL(__func__);
620  const RemminaProtocolFeature *feature;
621  RemminaProtocolPlugin* plugin;
622 
624 
625  if (plugin == NULL) {
626  return FALSE;
627  }
628 
629  for (feature = plugin->features; feature && feature->type; feature++) {
630  if (feature->type == ftype)
631  return TRUE;
632  }
633  return FALSE;
634 }
635 
637 {
638  TRACE_CALL(__func__);
639  GHashTable *pht;
640 
641  if (encrypted_settings_cache == NULL)
642  return FALSE;
643 
644  if (!(pht = g_hash_table_lookup(encrypted_settings_cache, pp->name)))
645  return FALSE;
646 
647  if (!g_hash_table_lookup(pht, setting))
648  return FALSE;
649 
650  return TRUE;
651 }
gboolean remmina_protocol_widget_get_expand(RemminaProtocolWidget *gp)
void remmina_protocol_widget_panel_show(RemminaProtocolWidget *gp)
static RemminaSecretPlugin * remmina_secret_plugin
const gchar * remmina_plugin_manager_get_canonical_setting_name(const RemminaProtocolSetting *setting)
void remmina_protocol_widget_set_error(RemminaProtocolWidget *gp, const gchar *fmt,...)
gboolean remmina_plugin_manager_is_encrypted_setting(RemminaProtocolPlugin *pp, const char *setting)
gint remmina_pref_get_scale_quality(void)
const gchar * remmina_file_get_string(RemminaFile *remminafile, const gchar *setting)
Definition: remmina_file.c:516
void remmina_protocol_widget_panel_hide(RemminaProtocolWidget *gp)
static void htdestroy(gpointer ht)
gchar * remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget *gp, gint default_port, gboolean port_plus)
Start an SSH tunnel if possible and return the host:port string.
GtkWindow * remmina_main_get_window()
void remmina_protocol_widget_chat_receive(RemminaProtocolWidget *gp, const gchar *text)
gint remmina_protocol_widget_get_width(RemminaProtocolWidget *gp)
gboolean remmina_plugin_native_load(RemminaPluginService *service, const char *name)
gboolean remmina_plugin_manager_loader_supported(const char *filetype)
gint remmina_protocol_widget_get_profile_remote_width(RemminaProtocolWidget *gp)
gint remmina_pref_get_sshtunnel_port(void)
gint remmina_protocol_widget_panel_auth(RemminaProtocolWidget *gp, RemminaMessagePanelFlags pflags, const gchar *title, const gchar *default_username, const gchar *default_password, const gchar *default_domain, const gchar *password_prompt)
void remmina_protocol_widget_save_cred(RemminaProtocolWidget *gp)
const gchar * remmina_file_get_filename(RemminaFile *remminafile)
Definition: remmina_file.c:210
static gint compare_secret_plugin_init_order(gconstpointer a, gconstpointer b)
gboolean remmina_protocol_widget_get_savepassword(RemminaProtocolWidget *gp)
GtkWidget * remmina_protocol_widget_gtkviewport(RemminaProtocolWidget *gp)
typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
Definition: types.h:44
gboolean remmina_protocol_widget_has_error(RemminaProtocolWidget *gp)
RemminaPluginType type
Definition: plugin.h:57
gboolean(* init)(struct _RemminaSecretPlugin *instance)
Definition: plugin.h:143
void remmina_protocol_widget_register_hostkey(RemminaProtocolWidget *gp, GtkWidget *widget)
gboolean remmina_protocol_widget_start_reverse_tunnel(RemminaProtocolWidget *gp, gint local_port)
G_BEGIN_DECLS typedef gboolean(* RemminaPluginFunc)(gchar *name, RemminaPlugin *plugin, gpointer data)
void remmina_plugin_manager_for_each_plugin(RemminaPluginType type, RemminaPluginFunc func, gpointer data)
gchar * remmina_protocol_widget_get_domain(RemminaProtocolWidget *gp)
GtkWidget * rcw_open_from_file_full(RemminaFile *remminafile, GCallback disconnect_cb, gpointer data, guint *handler)
Definition: rcw.c:4523
void remmina_widget_pool_register(GtkWidget *widget)
void _remmina_critical(const gchar *fun, const gchar *fmt,...)
Definition: remmina_log.c:382
gchar * remmina_file_get_secret(RemminaFile *remminafile, const gchar *setting)
Definition: remmina_file.c:551
gint remmina_pref_get_ssh_loglevel(void)
const RemminaProtocolFeature * features
Definition: plugin.h:77
RemminaFilePlugin * remmina_plugin_manager_get_export_file_handler(RemminaFile *remminafile)
const gchar * domain
Definition: plugin.h:60
void _remmina_warning(const gchar *fun, const gchar *fmt,...)
Definition: remmina_log.c:286
RemminaFilePlugin * remmina_plugin_manager_get_import_file_handler(const gchar *file)
RemminaSecretPlugin * remmina_plugin_manager_get_secret_plugin(void)
gchar * remmina_protocol_widget_get_cacert(RemminaProtocolWidget *gp)
void remmina_protocol_widget_lock_dynres(RemminaProtocolWidget *gp)
gint remmina_protocol_widget_get_height(RemminaProtocolWidget *gp)
void _remmina_audit(const gchar *fun, const gchar *fmt,...)
Definition: remmina_log.c:313
RemminaScaleMode remmina_protocol_widget_get_current_scale_mode(RemminaProtocolWidget *gp)
void remmina_protocol_widget_update_align(RemminaProtocolWidget *gp)
gdouble remmina_file_get_double(RemminaFile *remminafile, const gchar *setting, gdouble default_value)
Definition: remmina_file.c:629
gint remmina_protocol_widget_panel_authx509(RemminaProtocolWidget *gp)
void remmina_pref_set_value(const gchar *key, const gchar *value)
const gchar * description
Definition: plugin.h:59
const gchar * version
Definition: plugin.h:61
gboolean(* load)(struct _RemminaLanguageWrapperPlugin *instance, const gchar *plugin_file)
Definition: plugin.h:159
void _remmina_debug(const gchar *fun, const gchar *fmt,...)
Print a string in the Remmina Debug Windows and in the terminal.
Definition: remmina_log.c:259
void remmina_protocol_widget_set_display(RemminaProtocolWidget *gp, gint display)
void remmina_protocol_widget_set_width(RemminaProtocolWidget *gp, gint width)
static gboolean remmina_plugin_manager_show_for_each(RemminaPlugin *plugin, GtkListStore *store)
gchar * remmina_pref_get_value(const gchar *key)
gboolean remmina_pref_get_ssh_parseconfig(void)
const gchar * remmina_protocol_widget_get_name(RemminaProtocolWidget *gp)
const char * get_filename_ext(const char *filename)
void remmina_protocol_widget_panel_show_listen(RemminaProtocolWidget *gp, gint port)
void remmina_plugin_manager_show(GtkWindow *parent)
gboolean remmina_masterthread_exec_is_main_thread()
guint * remmina_pref_keymap_get_table(const gchar *keymap)
void remmina_protocol_widget_signal_connection_closed(RemminaProtocolWidget *gp)
RemminaPluginService remmina_plugin_manager_service
static const gchar * remmina_plugin_type_name[]
void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
void remmina_protocol_widget_desktop_resize(RemminaProtocolWidget *gp)
RemminaProtocolFeatureType type
Definition: types.h:73
gboolean(* export_test_func)(struct _RemminaFilePlugin *instance, RemminaFile *file)
Definition: plugin.h:109
const gchar * name
Definition: plugin.h:137
gint remmina_protocol_widget_panel_changed_certificate(RemminaProtocolWidget *gp, const gchar *subject, const gchar *issuer, const gchar *new_fingerprint, const gchar *old_fingerprint)
gboolean remmina_plugin_manager_query_feature_by_type(RemminaPluginType ptype, const gchar *name, RemminaProtocolFeatureType ftype)
gchar * remmina_protocol_widget_get_clientcert(RemminaProtocolWidget *gp)
void remmina_file_set_int(RemminaFile *remminafile, const gchar *setting, gint value)
Definition: remmina_file.c:585
void remmina_protocol_widget_unlock_dynres(RemminaProtocolWidget *gp)
gboolean remmina_gtksocket_available()
void remmina_protocol_widget_panel_show_retry(RemminaProtocolWidget *gp)
const gchar ** supported_extentions
Definition: plugin.h:156
const RemminaProtocolSetting * basic_settings
Definition: plugin.h:74
gint remmina_protocol_widget_panel_new_certificate(RemminaProtocolWidget *gp, const gchar *subject, const gchar *issuer, const gchar *fingerprint)
void remmina_plugin_manager_init()
gchar * remmina_file_get_datadir(void)
Return datadir_path from pref or first found data dir as per XDG specs.
gboolean remmina_protocol_widget_ssh_exec(RemminaProtocolWidget *gp, gboolean wait, const gchar *fmt,...)
gchar * remmina_protocol_widget_get_cacrl(RemminaProtocolWidget *gp)
void _remmina_info(const gchar *fmt,...)
Definition: remmina_log.c:206
RemminaProtocolFeatureType
Definition: types.h:46
void remmina_protocol_widget_set_height(RemminaProtocolWidget *gp, gint height)
RemminaProtocolSettingType type
Definition: types.h:118
void remmina_protocol_widget_emit_signal(RemminaProtocolWidget *gp, const gchar *signal_name)
RemminaFile * remmina_file_new(void)
Definition: remmina_file.c:93
guint remmina_pref_keymap_get_keyval(const gchar *keymap, guint keyval)
gboolean remmina_protocol_widget_is_closed(RemminaProtocolWidget *gp)
gchar * remmina_protocol_widget_get_clientkey(RemminaProtocolWidget *gp)
RemminaPluginType type
Definition: plugin.h:101
gint remmina_file_get_int(RemminaFile *remminafile, const gchar *setting, gint default_value)
Definition: remmina_file.c:603
gboolean remmina_protocol_widget_start_xport_tunnel(RemminaProtocolWidget *gp, RemminaXPortTunnelInitFunc init_func)
gboolean(* import_test_func)(struct _RemminaFilePlugin *instance, const gchar *from_file)
Definition: plugin.h:107
RemminaPlugin * remmina_plugin_manager_get_plugin(RemminaPluginType type, const gchar *name)
void remmina_protocol_widget_signal_connection_opened(RemminaProtocolWidget *gp)
static GPtrArray * remmina_plugin_table
gint remmina_protocol_widget_get_profile_remote_height(RemminaProtocolWidget *gp)
const gchar * name
Definition: plugin.h:67
gchar * remmina_protocol_widget_get_password(RemminaProtocolWidget *gp)
static gint remmina_plugin_manager_compare_func(RemminaPlugin **a, RemminaPlugin **b)
const RemminaProtocolSetting * advanced_settings
Definition: plugin.h:75
RemminaPluginType
Definition: plugin.h:46
static GHashTable * encrypted_settings_cache
void remmina_protocol_widget_set_expand(RemminaProtocolWidget *gp, gboolean expand)
void remmina_log_printf(const gchar *fmt,...)
Definition: remmina_log.c:411
static gboolean remmina_plugin_manager_show_for_each_stdout(RemminaPlugin *plugin)
void remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value)
Definition: remmina_file.c:469
void remmina_protocol_widget_send_keys_signals(GtkWidget *widget, const guint *keyvals, int keyvals_length, GdkEventType action)
void remmina_log_print(const gchar *text)
Definition: remmina_log.c:197
void _remmina_message(const gchar *fmt,...)
Definition: remmina_log.c:230
void remmina_file_unsave_passwords(RemminaFile *remminafile)
Definition: remmina_file.c:978
void remmina_protocol_widget_chat_close(RemminaProtocolWidget *gp)
void remmina_public_get_server_port(const gchar *server, gint defaultport, gchar **host, gint *port)
static gboolean remmina_plugin_manager_register_plugin(RemminaPlugin *plugin)
void remmina_plugin_manager_show_stdout()
RemminaFile * remmina_protocol_widget_get_file(RemminaProtocolWidget *gp)
static void init_settings_cache(RemminaPlugin *plugin)
N_("Unable to connect to VNC server")
Definition: vnc_plugin.c:953
gint remmina_public_open_unix_sock(const char *unixsock)
Return a file descriptor handle for a unix socket.
void remmina_protocol_widget_chat_open(RemminaProtocolWidget *gp, const gchar *name, void(*on_send)(RemminaProtocolWidget *gp, const gchar *text), void(*on_destroy)(RemminaProtocolWidget *gp))
const gchar * name
Definition: plugin.h:58
gchar * remmina_protocol_widget_get_username(RemminaProtocolWidget *gp)
void _remmina_error(const gchar *fun, const gchar *fmt,...)
Definition: remmina_log.c:355
const gchar * name
Definition: types.h:119