Greenbone Vulnerability Management Libraries  22.8.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 
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
17 
20 #define G_LOG_DOMAIN "libgvm util"
21 
27 static const gchar *authentication_methods[] = {"file", "ldap_connect",
28  "radius_connect", NULL};
29 
33 static gboolean initialized = FALSE;
34 
40 int
42 {
43 #ifdef ENABLE_LDAP_AUTH
44  return 1;
45 #else
46  return 0;
47 #endif /* ENABLE_LDAP_AUTH */
48 }
49 
55 int
57 {
58 #ifdef ENABLE_RADIUS_AUTH
59  return 1;
60 #else
61  return 0;
62 #endif /* ENABLE_RADIUS_AUTH */
63 }
64 
75 const gchar *
77 {
78  if (method >= AUTHENTICATION_METHOD_LAST)
79  return "ERROR";
80  return authentication_methods[method];
81 }
82 
88 int
90 {
91  if (initialized == TRUE)
92  {
93  g_warning ("gvm_auth_init called a second time.");
94  return -1;
95  }
96 
97  /* Init Libgcrypt. */
98 
99  /* Check if libgcrypt is already initialized */
100  if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
101  {
102  initialized = TRUE;
103  return 0;
104  }
105 
106  /* Version check should be the very first call because it makes sure that
107  * important subsystems are initialized.
108  * We pass NULL to gcry_check_version to disable the internal version mismatch
109  * test. */
110  if (!gcry_check_version (NULL))
111  {
112  g_critical ("%s: libgcrypt version check failed\n", __func__);
113  return -1;
114  }
115 
116  /* We don't want to see any warnings, e.g. because we have not yet parsed
117  * program options which might be used to suppress such warnings. */
118  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
119 
120  /* ... If required, other initialization goes here. Note that the process
121  * might still be running with increased privileges and that the secure
122  * memory has not been initialized. */
123 
124  /* Allocate a pool of 16k secure memory. This make the secure memory
125  * available and also drops privileges where needed. */
126  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
127 
128  /* It is now okay to let Libgcrypt complain when there was/is a problem with
129  * the secure memory. */
130  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
131 
132  /* ... If required, other initialization goes here. */
133 
134  /* Tell Libgcrypt that initialization has completed. */
135  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
136 
137  initialized = TRUE;
138 
139  return 0;
140 }
141 
153 gchar *
154 digest_hex (int gcrypt_algorithm, const guchar *digest)
155 {
156  unsigned int i;
157  gchar *hex;
158 
159  gcry_error_t err = gcry_md_test_algo (gcrypt_algorithm);
160  if (err != 0)
161  {
162  g_warning ("Could not select gcrypt algorithm: %s", gcry_strerror (err));
163  return NULL;
164  }
165 
166  hex = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm) * 2 + 1);
167  for (i = 0; i < gcry_md_get_algo_dlen (gcrypt_algorithm); i++)
168  {
169  g_snprintf (hex + i * 2, 3, "%02x", digest[i]);
170  }
171 
172  return hex;
173 }
174 
188 gchar *
189 get_password_hashes (const gchar *password)
190 {
191  g_assert (password);
192 
193  unsigned char *nonce_buffer[256];
194  guchar *seed = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
195  gchar *seed_hex = NULL;
196  gchar *seed_pass = NULL;
197  guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
198  gchar *hash_hex = NULL;
199  gchar *hashes_out = NULL;
200 
201  gcry_create_nonce (nonce_buffer, 256);
202  gcry_md_hash_buffer (GCRY_MD_MD5, seed, nonce_buffer, 256);
203  seed_hex = digest_hex (GCRY_MD_MD5, seed);
204  seed_pass = g_strconcat (seed_hex, password, NULL);
205  gcry_md_hash_buffer (GCRY_MD_MD5, hash, seed_pass, strlen (seed_pass));
206  hash_hex = digest_hex (GCRY_MD_MD5, hash);
207 
208  hashes_out = g_strjoin (" ", hash_hex, seed_hex, NULL);
209 
210  g_free (seed);
211  g_free (seed_hex);
212  g_free (seed_pass);
213  g_free (hash);
214  g_free (hash_hex);
215 
216  return hashes_out;
217 }
218 
227 gchar *
228 get_md5_hash_from_string (const gchar *string)
229 {
230  g_assert (string);
231 
232  gchar *hash_hex = NULL;
233  guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (GCRY_MD_MD5));
234 
235  gcry_md_hash_buffer (GCRY_MD_MD5, hash, string, strlen (string));
236  hash_hex = digest_hex (GCRY_MD_MD5, hash);
237 
238  g_free (hash);
239 
240  return hash_hex;
241 }
242 
252 int
253 gvm_authenticate_classic (const gchar *username, const gchar *password,
254  const gchar *hash_arg)
255 {
256  int gcrypt_algorithm = GCRY_MD_MD5; // FIX whatever configure used
257  int ret;
258  gchar *actual, *expect, *seed_pass;
259  guchar *hash;
260  gchar *hash_hex, **seed_hex, **split;
261 
262  (void) username;
263  if (hash_arg == NULL)
264  return 1;
265  actual = g_strdup (hash_arg);
266 
267  split = g_strsplit_set (g_strchomp (actual), " ", 2);
268  seed_hex = split + 1;
269  if (*split == NULL || *seed_hex == NULL)
270  {
271  g_warning ("Failed to split auth contents.");
272  g_strfreev (split);
273  g_free (actual);
274  return -1;
275  }
276 
277  seed_pass = g_strconcat (*seed_hex, password, NULL);
278  hash = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm));
279  gcry_md_hash_buffer (GCRY_MD_MD5, hash, seed_pass, strlen (seed_pass));
280  hash_hex = digest_hex (GCRY_MD_MD5, hash);
281 
282  expect = g_strjoin (" ", hash_hex, *seed_hex, NULL);
283 
284  g_strfreev (split);
285  g_free (seed_pass);
286  g_free (hash);
287  g_free (hash_hex);
288 
289  ret = strcmp (expect, actual) ? 1 : 0;
290  g_free (expect);
291  g_free (actual);
292  return ret;
293 }
gvm_auth_radius_enabled
int gvm_auth_radius_enabled(void)
Return whether libraries has been compiled with RADIUS support.
Definition: authutils.c:56
auth_method_t
enum authentication_method auth_method_t
Type for the numerical representation of the supported authentication methods.
Definition: authutils.h:31
get_password_hashes
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:189
gvm_auth_init
int gvm_auth_init(void)
Initializes Gcrypt.
Definition: authutils.c:89
authutils.h
Authentication mechanism(s).
get_md5_hash_from_string
gchar * get_md5_hash_from_string(const gchar *string)
Calculate the MD5 hash value for a given string.
Definition: authutils.c:228
gvm_authenticate_classic
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:253
auth_method_name
const gchar * auth_method_name(auth_method_t method)
Return name of auth_method_t.
Definition: authutils.c:76
gvm_auth_ldap_enabled
int gvm_auth_ldap_enabled(void)
Return whether libraries has been compiled with LDAP support.
Definition: authutils.c:41
AUTHENTICATION_METHOD_LAST
@ AUTHENTICATION_METHOD_LAST
Definition: authutils.h:26
authentication_methods
static const gchar * authentication_methods[]
Array of string representations of the supported authentication methods.
Definition: authutils.c:27
initialized
static gboolean initialized
Flag whether the config file was read.
Definition: authutils.c:33
digest_hex
gchar * digest_hex(int gcrypt_algorithm, const guchar *digest)
Generate a hexadecimal representation of a message digest.
Definition: authutils.c:154