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_passwd.c
Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  * In addition, as a special exception, the copyright holders give
21  * permission to link the code of portions of this program with the
22  * OpenSSL library under certain conditions as described in each
23  * individual source file, and distribute linked combinations
24  * including the two.
25  * You must obey the GNU General Public License in all respects
26  * for all of the code used other than OpenSSL. * If you modify
27  * file(s) with this exception, you may extend this exception to your
28  * version of the file(s), but you are not obligated to do so. * If you
29  * do not wish to do so, delete this exception statement from your
30  * version. * If you delete this exception statement from all source
31  * files in the program, then also delete it here.
32  *
33  */
34 
35 #include <stdlib.h>
36 
37 #include <glib/gi18n.h>
38 
39 #include "config.h"
40 #include "remmina_public.h"
41 #include "remmina_log.h"
42 #include "remmina_sodium.h"
43 #include "remmina_passwd.h"
45 
47 #define GET_OBJ(object_name) gtk_builder_get_object(remmina_passwd_dialog->builder, object_name)
48 
50 {
51  TRACE_CALL(__func__);
52  GtkCssProvider *provider;
53  const gchar *color;
54  const gchar *password;
55  const gchar *verify;
56  gboolean sensitive = FALSE;
57 
58  provider = gtk_css_provider_new();
59 
60  password = gtk_entry_get_text(remmina_passwd_dialog->entry_password);
61  verify = gtk_entry_get_text(remmina_passwd_dialog->entry_verify);
62  if (g_strcmp0(password, verify) == 0) {
63  color = g_strdup("green");
64  sensitive = TRUE;
65  } else
66  color = g_strdup("red");
67 
68  gtk_widget_set_sensitive (GTK_WIDGET(remmina_passwd_dialog->button_submit), sensitive);
69 
70  if (verify == NULL || verify[0] == '\0')
71  color = g_strdup("inherit");
72 
73  gtk_css_provider_load_from_data(provider,
74  g_strdup_printf(
75  ".entry_verify {\n"
76  " color: %s;\n"
77  "}\n"
78  , color)
79  , -1, NULL);
80  gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
81  GTK_STYLE_PROVIDER(provider),
82  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
83 
84  gtk_widget_queue_draw(GTK_WIDGET(remmina_passwd_dialog->entry_verify));
85  g_object_unref(provider);
86 }
87 
88 static void remmina_passwd_password_activate(GtkEntry *entry, gpointer user_data)
89 {
90  TRACE_CALL(__func__);
91 
92  gtk_widget_grab_focus(GTK_WIDGET(remmina_passwd_dialog->entry_verify));
93 
94 }
95 
96 static void remmina_passwd_cancel_clicked(GtkButton *btn, gpointer user_data)
97 {
98  TRACE_CALL(__func__);
99  gtk_dialog_response (remmina_passwd_dialog->dialog, GTK_RESPONSE_CANCEL);
100 }
101 
102 static void remmina_passwd_submit_clicked(GtkButton *btn, gpointer user_data)
103 {
104  TRACE_CALL(__func__);
105  remmina_passwd_dialog->password = gtk_entry_get_text(
106  GTK_ENTRY(remmina_passwd_dialog->entry_verify));
107  gtk_dialog_response (remmina_passwd_dialog->dialog, GTK_RESPONSE_ACCEPT);
108 }
109 
110 gboolean remmina_passwd(GtkWindow *parent, gchar **unlock_password)
111 {
112  TRACE_CALL(__func__);
113 
114  remmina_passwd_dialog = g_new0(RemminaPasswdDialog, 1);
115  gboolean rc = FALSE;
116 
117  remmina_passwd_dialog->builder = remmina_public_gtk_builder_new_from_resource("/org/remmina/Remmina/src/../data/ui/remmina_passwd.glade");
118  remmina_passwd_dialog->dialog = GTK_DIALOG(GET_OBJ("RemminaPasswdDialog"));
119  if (parent)
120  gtk_window_set_transient_for(GTK_WINDOW(remmina_passwd_dialog->dialog), parent);
121 
122  remmina_passwd_dialog->entry_password = GTK_ENTRY(GET_OBJ("entry_password"));
123  remmina_passwd_dialog->entry_verify = GTK_ENTRY(GET_OBJ("entry_verify"));
124  gtk_entry_set_activates_default(GTK_ENTRY(remmina_passwd_dialog->entry_verify), TRUE);
125  remmina_passwd_dialog->button_submit = GTK_BUTTON(GET_OBJ("button_submit"));
126  gtk_widget_set_can_default(GTK_WIDGET(remmina_passwd_dialog->button_submit), TRUE);
127  gtk_widget_grab_default(GTK_WIDGET(remmina_passwd_dialog->button_submit));
128  remmina_passwd_dialog->button_cancel = GTK_BUTTON(GET_OBJ("button_cancel"));
129 
130  g_signal_connect(remmina_passwd_dialog->entry_password, "activate",
131  G_CALLBACK(remmina_passwd_password_activate), (gpointer)remmina_passwd_dialog);
132  g_signal_connect(remmina_passwd_dialog->button_submit, "clicked",
133  G_CALLBACK(remmina_passwd_submit_clicked), (gpointer)remmina_passwd_dialog);
134  g_signal_connect(remmina_passwd_dialog->button_cancel, "clicked",
135  G_CALLBACK(remmina_passwd_cancel_clicked), (gpointer)remmina_passwd_dialog);
136 
137  /* Connect signals */
138  gtk_builder_connect_signals(remmina_passwd_dialog->builder, NULL);
139 
140  int result = gtk_dialog_run(remmina_passwd_dialog->dialog);
141  switch (result)
142  {
143  case GTK_RESPONSE_ACCEPT:
144 #if SODIUM_VERSION_INT >= 90200
145  //REMMINA_DEBUG ("Password before encryption: %s", remmina_passwd_dialog->password);
146  *unlock_password = remmina_sodium_pwhash_str(remmina_passwd_dialog->password);
147 #else
148  *unlock_password = g_strdup(remmina_passwd_dialog->password);
149 #endif
150  //REMMINA_DEBUG ("Password after encryption is: %s", *unlock_password);
151  remmina_passwd_dialog->password = NULL;
152  rc = TRUE;
153  break;
154  default:
155  remmina_passwd_dialog->password = NULL;
156  *unlock_password = NULL;
157  rc = FALSE;
158  break;
159  }
160  gtk_widget_destroy(GTK_WIDGET(remmina_passwd_dialog->dialog));
161  remmina_passwd_dialog->dialog = NULL;
162  return rc;
163 }
GtkButton * button_submit
static void remmina_passwd_cancel_clicked(GtkButton *btn, gpointer user_data)
const gchar * password
GtkDialog * dialog
gboolean remmina_passwd(GtkWindow *parent, gchar **unlock_password)
static void remmina_passwd_password_activate(GtkEntry *entry, gpointer user_data)
gchar * remmina_sodium_pwhash_str(const gchar *pass)
GtkBuilder * remmina_public_gtk_builder_new_from_resource(gchar *resource)
void remmina_passwd_repwd_on_changed(GtkEditable *editable, RemminaPasswdDialog *dialog)
GtkButton * button_cancel
GtkBuilder * builder
GtkEntry * entry_password
static void remmina_passwd_submit_clicked(GtkButton *btn, gpointer user_data)
static RemminaPasswdDialog * remmina_passwd_dialog