Greenbone Vulnerability Management Libraries 22.12.2
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
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 int i;
94 for (i = 0; i < 1000; i++)
95 if (authentication_methods[i] == NULL)
96 break;
97 else if (strcmp (authentication_methods[i], name) == 0)
98 return 1;
99 return 0;
100}
101
107int
109{
110 if (initialized == TRUE)
111 {
112 g_warning ("gvm_auth_init called a second time.");
113 return -1;
114 }
115
116 /* Init Libgcrypt. */
117
118 /* Check if libgcrypt is already initialized */
119 if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
120 {
121 initialized = TRUE;
122 return 0;
123 }
124
125 /* Version check should be the very first call because it makes sure that
126 * important subsystems are initialized.
127 * We pass NULL to gcry_check_version to disable the internal version mismatch
128 * test. */
129 if (!gcry_check_version (NULL))
130 {
131 g_critical ("%s: libgcrypt version check failed\n", __func__);
132 return -1;
133 }
134
135 /* We don't want to see any warnings, e.g. because we have not yet parsed
136 * program options which might be used to suppress such warnings. */
137 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
138
139 /* ... If required, other initialization goes here. Note that the process
140 * might still be running with increased privileges and that the secure
141 * memory has not been initialized. */
142
143 /* Allocate a pool of 16k secure memory. This make the secure memory
144 * available and also drops privileges where needed. */
145 gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
146
147 /* It is now okay to let Libgcrypt complain when there was/is a problem with
148 * the secure memory. */
149 gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
150
151 /* ... If required, other initialization goes here. */
152
153 /* Tell Libgcrypt that initialization has completed. */
154 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
155
156 initialized = TRUE;
157
158 return 0;
159}
160
172gchar *
173digest_hex (int gcrypt_algorithm, const guchar *digest)
174{
175 unsigned int i;
176 gchar *hex;
177
178 gcry_error_t err = gcry_md_test_algo (gcrypt_algorithm);
179 if (err != 0)
180 {
181 g_warning ("Could not select gcrypt algorithm: %s", gcry_strerror (err));
182 return NULL;
183 }
184
185 hex = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm) * 2 + 1);
186 for (i = 0; i < gcry_md_get_algo_dlen (gcrypt_algorithm); i++)
187 {
188 g_snprintf (hex + i * 2, 3, "%02x", digest[i]);
189 }
190
191 return hex;
192}
193
207gchar *
208get_password_hashes (const gchar *password)
209{
210 g_assert (password);
211
212 unsigned char *nonce_buffer[256];
213 guchar *seed = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
214 gchar *seed_hex = NULL;
215 gchar *seed_pass = NULL;
216 guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
217 gchar *hash_hex = NULL;
218 gchar *hashes_out = NULL;
219
220 gcry_create_nonce (nonce_buffer, 256);
221 gcry_md_hash_buffer (GCRY_MD_MD5, seed, nonce_buffer, 256);
222 seed_hex = digest_hex (GCRY_MD_MD5, seed);
223 seed_pass = g_strconcat (seed_hex, password, NULL);
224 gcry_md_hash_buffer (GCRY_MD_MD5, hash, seed_pass, strlen (seed_pass));
225 hash_hex = digest_hex (GCRY_MD_MD5, hash);
226
227 hashes_out = g_strjoin (" ", hash_hex, seed_hex, NULL);
228
229 g_free (seed);
230 g_free (seed_hex);
231 g_free (seed_pass);
232 g_free (hash);
233 g_free (hash_hex);
234
235 return hashes_out;
236}
237
246gchar *
247get_md5_hash_from_string (const gchar *string)
248{
249 g_assert (string);
250
251 gchar *hash_hex = NULL;
252 guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
253
254 gcry_md_hash_buffer (GCRY_MD_MD5, hash, string, strlen (string));
255 hash_hex = digest_hex (GCRY_MD_MD5, hash);
256
257 g_free (hash);
258
259 return hash_hex;
260}
261
271int
272gvm_authenticate_classic (const gchar *username, const gchar *password,
273 const gchar *hash_arg)
274{
275 int gcrypt_algorithm = GCRY_MD_MD5; // FIX whatever configure used
276 int ret;
277 gchar *actual, *expect, *seed_pass;
278 guchar *hash;
279 gchar *hash_hex, **seed_hex, **split;
280
281 (void) username;
282 if (hash_arg == NULL)
283 return 1;
284 actual = g_strdup (hash_arg);
285
286 split = g_strsplit_set (g_strchomp (actual), " ", 2);
287 seed_hex = split + 1;
288 if (*split == NULL || *seed_hex == NULL)
289 {
290 g_warning ("Failed to split auth contents.");
291 g_strfreev (split);
292 g_free (actual);
293 return -1;
294 }
295
296 seed_pass = g_strconcat (*seed_hex, password, NULL);
297 hash = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm));
298 gcry_md_hash_buffer (GCRY_MD_MD5, hash, seed_pass, strlen (seed_pass));
299 hash_hex = digest_hex (GCRY_MD_MD5, hash);
300
301 expect = g_strjoin (" ", hash_hex, *seed_hex, NULL);
302
303 g_strfreev (split);
304 g_free (seed_pass);
305 g_free (hash);
306 g_free (hash_hex);
307
308 ret = strcmp (expect, actual) ? 1 : 0;
309 g_free (expect);
310 g_free (actual);
311 return ret;
312}
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:247
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:272
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:108
gchar * digest_hex(int gcrypt_algorithm, const guchar *digest)
Generate a hexadecimal representation of a message digest.
Definition authutils.c:173
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:208
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