Remmina - The GTK+ Remote Desktop Client  v1.4.2
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_unlock.c
Go to the documentation of this file.
1 /*
2  * Remmina - The GTK+ Remote Desktop Client
3  * Copyright (C) 2016-2020 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 <gtk/gtk.h>
38 #include <glib/gi18n.h>
39 #include <glib.h>
40 #include <glib/gprintf.h>
41 
42 #include "config.h"
43 #include "remmina_sodium.h"
44 #include "remmina_pref.h"
45 #include "remmina_unlock.h"
46 #include "remmina_public.h"
48 
49 #if SODIUM_VERSION_INT >= 90200
51 #define GET_OBJ(object_name) gtk_builder_get_object(remmina_unlock_dialog->builder, object_name)
52 
53 GTimer *timer;
54 gboolean isinit;
55 
57 {
58  TRACE_CALL(__func__);
59 
60  timer = g_timer_new();
61  g_info("Unlock Master Password timer initialized");
62 }
63 
64 static void remmina_unlock_timer_reset(gpointer user_data)
65 {
66  TRACE_CALL(__func__);
67 
68  g_timer_reset(timer);
69  g_info("Unlock Master Password timer reset");
70 }
71 
73 {
74  TRACE_CALL(__func__);
75 
76  g_timer_destroy(timer);
77 }
78 
79 static void remmina_unlock_unlock_clicked(GtkButton *btn, gpointer user_data)
80 {
81  TRACE_CALL(__func__);
82  //g_timer_reset(remmina_unlock_dialog->timer);
83 
84  gchar *unlock_password;
85  const gchar *entry_passwd;
86  gint rc;
87 
88  unlock_password = remmina_pref_get_value("unlock_password");
89  entry_passwd = gtk_entry_get_text(remmina_unlock_dialog->entry_unlock);
90  rc = remmina_sodium_pwhash_str_verify(unlock_password, entry_passwd);
91  g_info("remmina_sodium_pwhash_str_verify returned %i", rc);
92 
93  if (rc == 0) {
94  g_info("Passphrase veryfied successfully");
95  remmina_unlock_timer_reset(remmina_unlock_dialog);
96  gtk_widget_destroy(GTK_WIDGET(remmina_unlock_dialog->dialog));
97  remmina_unlock_dialog->dialog = NULL;
98  } else {
99  g_warning ("Passphrase is wrong, to reset it, you can edit the remmina.pref file by hand");
100  }
101 }
102 
103 static void remmina_unlock_cancel_clicked(GtkButton *btn, gpointer user_data)
104 {
105  TRACE_CALL(__func__);
106  remmina_unlock_dialog->retval = 0;
107  gtk_widget_destroy(GTK_WIDGET(remmina_unlock_dialog->dialog));
108  remmina_unlock_dialog->dialog = NULL;
109 }
110 
111 gint remmina_unlock_new(GtkWindow *parent)
112 {
113  TRACE_CALL(__func__);
114 
115  gdouble unlock_timeout;
116  gdouble elapsed = 0.0;
117  gboolean lock = TRUE;
118 
119  unlock_timeout = remmina_pref.unlock_timeout;
120 
121 
122  remmina_unlock_dialog = g_new0(RemminaUnlockDialog, 1);
123  remmina_unlock_dialog->retval = 1;
124 
125  if (timer == NULL)
127  if (timer != NULL)
128  elapsed = g_timer_elapsed(timer, NULL);
129  if (((int)unlock_timeout - elapsed) < 0) lock = TRUE;
130  if (((int)unlock_timeout - elapsed) >= 0) lock = FALSE;
131  /* timer & timout = 0 */
132  if (timer != NULL && (int)unlock_timeout == 0) lock = FALSE;
133  /* first time and timout = 30 */
134  if (isinit == 0 && (int)unlock_timeout >= 0) {
135  lock = TRUE;
136  isinit = TRUE;
137  }
138  /* first time and timout = 0 */
139  if (isinit == 0 && (int)unlock_timeout == 0) {
140  lock = TRUE;
141  isinit = TRUE;
142  }
143  g_info("Based on settings and current status, the unlock dialog is set to %d", lock);
144 
145  remmina_unlock_dialog->builder = remmina_public_gtk_builder_new_from_file("remmina_unlock.glade");
146  remmina_unlock_dialog->dialog = GTK_DIALOG(gtk_builder_get_object(remmina_unlock_dialog->builder, "RemminaUnlockDialog"));
147  if (parent)
148  gtk_window_set_transient_for(GTK_WINDOW(remmina_unlock_dialog->dialog), parent);
149 
150  remmina_unlock_dialog->entry_unlock = GTK_ENTRY(GET_OBJ("entry_unlock"));
151  gtk_entry_set_activates_default(GTK_ENTRY(remmina_unlock_dialog->entry_unlock), TRUE);
152  remmina_unlock_dialog->button_unlock = GTK_BUTTON(GET_OBJ("button_unlock"));
153  gtk_widget_set_can_default(GTK_WIDGET(remmina_unlock_dialog->button_unlock), TRUE);
154  gtk_widget_grab_default(GTK_WIDGET(remmina_unlock_dialog->button_unlock));
155  remmina_unlock_dialog->button_unlock_cancel = GTK_BUTTON(GET_OBJ("button_unlock_cancel"));
156 
157  g_signal_connect(remmina_unlock_dialog->button_unlock, "clicked",
158  G_CALLBACK(remmina_unlock_unlock_clicked), (gpointer)remmina_unlock_dialog);
159  g_signal_connect(remmina_unlock_dialog->button_unlock_cancel, "clicked",
160  G_CALLBACK(remmina_unlock_cancel_clicked), (gpointer)remmina_unlock_dialog);
161  g_signal_connect (remmina_unlock_dialog->dialog, "close",
162  G_CALLBACK (remmina_unlock_cancel_clicked), (gpointer)remmina_unlock_dialog);
163 
164  /* Connect signals */
165  gtk_builder_connect_signals(remmina_unlock_dialog->builder, NULL);
166 
167  if (remmina_pref_get_boolean("use_master_password")
168  && (g_strcmp0(remmina_pref_get_value("unlock_password"), "") != 0)
169  && lock != 0)
170  gtk_dialog_run(remmina_unlock_dialog->dialog);
171  return(remmina_unlock_dialog->retval);
172 }
173 
174 #else
175 gint remmina_unlock_new(GtkWindow *parent)
176 {
177  return 1;
178 }
179 #endif
GtkBuilder * builder
GtkBuilder * remmina_public_gtk_builder_new_from_file(gchar *filename)
static void remmina_unlock_cancel_clicked(GtkButton *btn, gpointer user_data)
GtkButton * button_unlock
gchar * remmina_pref_get_value(const gchar *key)
gint remmina_sodium_pwhash_str_verify(const char *key, const char *pass)
GTimer * timer
gint unlock_timeout
Definition: remmina_pref.h:122
GtkButton * button_unlock_cancel
static void remmina_unlock_unlock_clicked(GtkButton *btn, gpointer user_data)
static RemminaUnlockDialog * remmina_unlock_dialog
static void remmina_unlock_timer_reset(gpointer user_data)
static void remmina_unlock_timer_init()
gboolean remmina_pref_get_boolean(const gchar *key)
void remmina_unlock_timer_destroy()
RemminaPref remmina_pref
Definition: rcw.c:73
gboolean isinit
gint remmina_unlock_new(GtkWindow *parent)