Greenbone Vulnerability Management Libraries 22.30.0
authutils.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2023 Greenbone AG
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
10
11#include "authutils.h"
12
13#include <gcrypt.h> /* for gcry_md_get_algo_dlen, gcry_control, gcry_md_alg... */
14#include <string.h> /* for strcmp */
15
16#undef G_LOG_DOMAIN
20#define G_LOG_DOMAIN "libgvm util"
21
27static const gchar *authentication_methods[] = {"file", "ldap_connect",
28 "radius_connect", NULL};
29
33static gboolean initialized = FALSE;
34
40int
42{
43#ifdef ENABLE_LDAP_AUTH
44 return 1;
45#else
46 return 0;
47#endif /* ENABLE_LDAP_AUTH */
48}
49
55int
57{
58#ifdef ENABLE_RADIUS_AUTH
59 return 1;
60#else
61 return 0;
62#endif /* ENABLE_RADIUS_AUTH */
63}
64
75const gchar *
77{
78 if (method >= AUTHENTICATION_METHOD_LAST)
79 return "ERROR";
80 return authentication_methods[method];
81}
82
90int
91auth_method_name_valid (const gchar *name)
92{
93 if (name == NULL)
94 return 0;
95 for (int i = 0; i < 1000; i++)
96 if (authentication_methods[i] == NULL)
97 break;
98 else if (strcmp (authentication_methods[i], name) == 0)
99 return 1;
100 return 0;
101}
102
108int
110{
111 if (initialized == TRUE)
112 {
113 g_warning ("gvm_auth_init called a second time.");
114 return -1;
115 }
116
117 /* Init Libgcrypt. */
118
119 /* Check if libgcrypt is already initialized */
120 if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
121 {
122 initialized = TRUE;
123 return 0;
124 }
125
126 /* Version check should be the very first call because it makes sure that
127 * important subsystems are initialized.
128 * We pass NULL to gcry_check_version to disable the internal version mismatch
129 * test. */
130 if (!gcry_check_version (NULL))
131 {
132 g_critical ("%s: libgcrypt version check failed\n", __func__);
133 return -1;
134 }
135
136 /* We don't want to see any warnings, e.g. because we have not yet parsed
137 * program options which might be used to suppress such warnings. */
138 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
139
140 /* ... If required, other initialization goes here. Note that the process
141 * might still be running with increased privileges and that the secure
142 * memory has not been initialized. */
143
144 /* Allocate a pool of 16k secure memory. This make the secure memory
145 * available and also drops privileges where needed. */
146 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
147
148 /* It is now okay to let Libgcrypt complain when there was/is a problem with
149 * the secure memory. */
150 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
151
152 /* ... If required, other initialization goes here. */
153
154 /* Tell Libgcrypt that initialization has completed. */
155 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
156
157 initialized = TRUE;
158
159 return 0;
160}
161
174gchar *
175digest_hex (int gcrypt_algorithm, const guchar *digest)
176{
177 unsigned int i;
178 gchar *hex;
179
180 gcry_error_t err = gcry_md_test_algo (gcrypt_algorithm);
181 if (err != 0)
182 {
183 g_warning ("Could not select gcrypt algorithm: %s", gcry_strerror (err));
184 return NULL;
185 }
186
187 hex = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm) * 2 + 1);
188 for (i = 0; i < gcry_md_get_algo_dlen (gcrypt_algorithm); i++)
189 {
190 g_snprintf (hex + i * 2, 3, "%02x", digest[i]);
191 }
192
193 return hex;
194}
195
209gchar *
210get_password_hashes (const gchar *password)
211{
212 g_assert (password);
213
214 unsigned char *nonce_buffer[256];
215 guchar *seed = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
216 gchar *seed_hex = NULL;
217 gchar *seed_pass = NULL;
218 guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
219 gchar *hash_hex = NULL;
220 gchar *hashes_out = NULL;
221
222 gcry_create_nonce (nonce_buffer, 256);
223 gcry_md_hash_buffer (GCRY_MD_MD5, seed, nonce_buffer, 256);
224 seed_hex = digest_hex (GCRY_MD_MD5, seed);
225 seed_pass = g_strconcat (seed_hex, password, NULL);
226 gcry_md_hash_buffer (GCRY_MD_MD5, hash, seed_pass, strlen (seed_pass));
227 hash_hex = digest_hex (GCRY_MD_MD5, hash);
228
229 hashes_out = g_strjoin (" ", hash_hex, seed_hex, NULL);
230
231 g_free (seed);
232 g_free (seed_hex);
233 g_free (seed_pass);
234 g_free (hash);
235 g_free (hash_hex);
236
237 return hashes_out;
238}
239
248gchar *
249get_md5_hash_from_string (const gchar *string)
250{
251 g_assert (string);
252
253 gchar *hash_hex = NULL;
254 guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
255
256 gcry_md_hash_buffer (GCRY_MD_MD5, hash, string, strlen (string));
257 hash_hex = digest_hex (GCRY_MD_MD5, hash);
258
259 g_free (hash);
260
261 return hash_hex;
262}
263
273int
274gvm_authenticate_classic (const gchar *username, const gchar *password,
275 const gchar *hash_arg)
276{
277 int gcrypt_algorithm = GCRY_MD_MD5; // FIX whatever configure used
278 int ret;
279 gchar *actual, *expect, *seed_pass;
280 guchar *hash;
281 gchar *hash_hex, **seed_hex, **split;
282
283 (void) username;
284 if (hash_arg == NULL)
285 return 1;
286 actual = g_strdup (hash_arg);
287
288 split = g_strsplit_set (g_strchomp (actual), " ", 2);
289 seed_hex = split + 1;
290 if (*split == NULL || *seed_hex == NULL)
291 {
292 g_warning ("Failed to split auth contents.");
293 g_strfreev (split);
294 g_free (actual);
295 return -1;
296 }
297
298 seed_pass = g_strconcat (*seed_hex, password, NULL);
299 hash = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm));
300 gcry_md_hash_buffer (GCRY_MD_MD5, hash, seed_pass, strlen (seed_pass));
301 hash_hex = digest_hex (GCRY_MD_MD5, hash);
302
303 expect = g_strjoin (" ", hash_hex, *seed_hex, NULL);
304
305 g_strfreev (split);
306 g_free (seed_pass);
307 g_free (hash);
308 g_free (hash_hex);
309
310 ret = strcmp (expect, actual) ? 1 : 0;
311 g_free (expect);
312 g_free (actual);
313 return ret;
314}
int auth_method_name_valid(const gchar *name)
Check if name is a valid auth method name.
Definition authutils.c:91
int gvm_auth_radius_enabled(void)
Return whether libraries has been compiled with RADIUS support.
Definition authutils.c:56
gchar * get_md5_hash_from_string(const gchar *string)
Calculate the MD5 hash value for a given string.
Definition authutils.c:249
int gvm_authenticate_classic(const gchar *username, const gchar *password, const gchar *hash_arg)
Authenticate a credential pair against user file contents.
Definition authutils.c:274
static const gchar * authentication_methods[]
Array of string representations of the supported authentication methods.
Definition authutils.c:27
int gvm_auth_init(void)
Initializes Gcrypt.
Definition authutils.c:109
gchar * digest_hex(int gcrypt_algorithm, const guchar *digest)
Generate a hexadecimal representation of a message digest.
Definition authutils.c:175
gchar * get_password_hashes(const gchar *password)
Generate a pair of md5 hashes to be used in the "auth/hash" file for the user.
Definition authutils.c:210
static gboolean initialized
Flag whether the config file was read.
Definition authutils.c:33
int gvm_auth_ldap_enabled(void)
Return whether libraries has been compiled with LDAP support.
Definition authutils.c:41
const gchar * auth_method_name(auth_method_t method)
Return name of auth_method_t.
Definition authutils.c:76
Authentication mechanism(s).
enum authentication_method auth_method_t
Type for the numerical representation of the supported authentication methods.
Definition authutils.h:31
@ AUTHENTICATION_METHOD_LAST
Definition authutils.h:26