Remmina - The GTK+ Remote Desktop Client  v1.4.34
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_sodium.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 
57 #include <string.h>
58 
59 #if defined(__linux__)
60 # include <fcntl.h>
61 # include <unistd.h>
62 # include <sys/ioctl.h>
63 # include <linux/random.h>
64 #endif
65 
66 #include "config.h"
67 #include <glib.h>
68 #include "remmina_pref.h"
70 
71 #include "remmina_sodium.h"
72 #if SODIUM_VERSION_INT >= 90200
73 
74 gchar *remmina_sodium_pwhash(const gchar *pass)
75 {
76  TRACE_CALL(__func__);
77  g_info("Generating passphrase (may take a while)...");
78  /* Create a random salt for the key derivation function */
79  unsigned char salt[crypto_pwhash_SALTBYTES] = { 0 };
80  randombytes_buf(salt, sizeof salt);
81 
82  unsigned long long opslimit;
83  size_t memlimit;
84 
85  switch (remmina_pref.enc_mode) {
87  opslimit = crypto_pwhash_OPSLIMIT_MODERATE;
88  memlimit = crypto_pwhash_MEMLIMIT_MODERATE;
89  break;
91  opslimit = crypto_pwhash_OPSLIMIT_SENSITIVE;
92  memlimit = crypto_pwhash_MEMLIMIT_SENSITIVE;
93  break;
94  case RM_ENC_MODE_GCRYPT:
95  case RM_ENC_MODE_SECRET:
97  default:
98  opslimit = crypto_pwhash_OPSLIMIT_INTERACTIVE;
99  memlimit = crypto_pwhash_MEMLIMIT_INTERACTIVE;
100  break;
101  }
102 
103  /* Use argon2 to convert password to a full size key */
104  unsigned char key[crypto_secretbox_KEYBYTES];
105  if (crypto_pwhash(key, sizeof key, pass, strlen(pass), salt,
106  opslimit,
107  memlimit,
108  crypto_pwhash_ALG_DEFAULT) != 0) {
109  g_error("%s - Out of memory!", __func__);
110  exit(1);
111  }
112 
113  g_info("%s - Password hashed", __func__);
114  return g_strdup((const char *)key);
115 }
116 
117 gchar *remmina_sodium_pwhash_str(const gchar *pass)
118 {
119  TRACE_CALL(__func__);
120  g_info("Generating passphrase (may take a while)...");
121  /* Create a random salt for the key derivation function */
122  unsigned char salt[crypto_pwhash_SALTBYTES] = { 0 };
123  randombytes_buf(salt, sizeof salt);
124 
125  unsigned long long opslimit;
126  size_t memlimit;
127 
128  switch (remmina_pref.enc_mode) {
130  opslimit = crypto_pwhash_OPSLIMIT_MODERATE;
131  memlimit = crypto_pwhash_MEMLIMIT_MODERATE;
132  break;
134  opslimit = crypto_pwhash_OPSLIMIT_SENSITIVE;
135  memlimit = crypto_pwhash_MEMLIMIT_SENSITIVE;
136  break;
137  case RM_ENC_MODE_GCRYPT:
138  case RM_ENC_MODE_SECRET:
140  default:
141  opslimit = crypto_pwhash_OPSLIMIT_INTERACTIVE;
142  memlimit = crypto_pwhash_MEMLIMIT_INTERACTIVE;
143  break;
144  }
145 
146  /* Use argon2 to convert password to a full size key */
147  char key[crypto_pwhash_STRBYTES];
148  if (crypto_pwhash_str(key, pass, strlen(pass),
149  opslimit,
150  memlimit) != 0) {
151  g_error("%s - Out of memory!", __func__);
152  exit(1);
153  }
154 
155  g_info("%s - Password hashed", __func__);
156  return g_strdup((const char *)key);
157 }
158 
159 gint remmina_sodium_pwhash_str_verify(const char *key, const char *pass)
160 {
161  TRACE_CALL(__func__);
162 
163  gint rc;
164 
165  rc = crypto_pwhash_str_verify(key, pass, strlen(pass));
166 
167  return rc;
168 }
169 
171 {
172  TRACE_CALL(__func__);
173 #if defined(__linux__) && defined(RNDGETENTCNT)
174  int fd;
175  int c;
176 
177  if ((fd = open("/dev/random", O_RDONLY)) != -1) {
178  if (ioctl(fd, RNDGETENTCNT, &c) == 0 && c < 160) {
179  g_printerr("This system doesn't provide enough entropy to quickly generate high-quality random numbers.\n"
180  "Installing the rng-utils/rng-tools, jitterentropy or haveged packages may help.\n"
181  "On virtualized Linux environments, also consider using virtio-rng.\n"
182  "The service will not start until enough entropy has been collected.\n");
183  }
184  (void)close(fd);
185  }
186 #endif
187 
188  if (sodium_init() < 0)
189  g_critical("%s - Failed to initialize sodium, it is not safe to use", __func__);
190 }
191 
192 #endif
RemminaPref remmina_pref
Definition: rcw.c:79
@ RM_ENC_MODE_SODIUM_SENSITIVE
Definition: remmina_pref.h:96
@ RM_ENC_MODE_GCRYPT
Definition: remmina_pref.h:97
@ RM_ENC_MODE_SODIUM_INTERACTIVE
Definition: remmina_pref.h:94
@ RM_ENC_MODE_SECRET
Definition: remmina_pref.h:93
@ RM_ENC_MODE_SODIUM_MODERATE
Definition: remmina_pref.h:95
void remmina_sodium_init(void)
gchar * remmina_sodium_pwhash_str(const gchar *pass)
gint remmina_sodium_pwhash_str_verify(const char *key, const char *pass)
gchar * remmina_sodium_pwhash(const gchar *pass)