OpenVAS Libraries  9.0.3
openvas_auth.c
Go to the documentation of this file.
1 /* OpenVAS Libraries
2  * $Id$
3  * Description: Authentication mechanism(s).
4  *
5  * Authors:
6  * Matthew Mundell <matt@mundell.ukfsn.org>
7  * Michael Wiegand <michael.wiegand@greenbone.net>
8  * Felix Wolfsteller <felix.wolfsteller@intevation.de>
9  *
10  * Copyright:
11  * Copyright (C) 2009,2010 Greenbone Networks GmbH
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
26  * USA.
27  */
28 
29 #include "openvas_auth.h"
30 
31 #ifndef _WIN32
32 #include "openvas_uuid.h"
33 #endif
34 
35 #include "../base/openvas_file.h"
36 #include "../base/array.h"
37 
38 #include <errno.h>
39 #include <gcrypt.h>
40 #include <glib/gstdio.h>
41 
42 #undef G_LOG_DOMAIN
43 
46 #define G_LOG_DOMAIN "lib auth"
47 
53 static const gchar *authentication_methods[] = { "file",
54  "ldap_connect",
55  "radius_connect",
56  NULL };
57 
59 static gboolean initialized = FALSE;
60 
66 int
68 {
69 #ifdef ENABLE_LDAP_AUTH
70  return 1;
71 #else
72  return 0;
73 #endif /* ENABLE_LDAP_AUTH */
74 }
75 
81 int
83 {
84 #ifdef ENABLE_RADIUS_AUTH
85  return 1;
86 #else
87  return 0;
88 #endif /* ENABLE_RADIUS_AUTH */
89 }
90 
101 const gchar *
103 {
104  if (method >= AUTHENTICATION_METHOD_LAST)
105  return "ERROR";
106  return authentication_methods[method];
107 }
108 
114 int
116 {
117  if (initialized == TRUE)
118  {
119  g_warning ("openvas_auth_init called a second time.");
120  return -1;
121  }
122 
123  /* Init Libgcrypt. */
124 
125  /* Version check should be the very first call because it makes sure that
126  * important subsystems are intialized.
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", __FUNCTION__);
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 intialized. */
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 
166 void
168 {
170 }
171 
183 gchar *
184 digest_hex (int gcrypt_algorithm, const guchar * digest)
185 {
186  unsigned int i;
187  gchar *hex;
188 
189  gcry_error_t err = gcry_md_test_algo (gcrypt_algorithm);
190  if (err != 0)
191  {
192  g_warning ("Could not select gcrypt algorithm: %s", gcry_strerror (err));
193  return NULL;
194  }
195 
196  hex = g_malloc0 (gcry_md_get_algo_dlen (gcrypt_algorithm) * 2 + 1);
197  for (i = 0; i < gcry_md_get_algo_dlen (gcrypt_algorithm); i++)
198  {
199  g_snprintf (hex + i * 2, 3, "%02x", digest[i]);
200  }
201 
202  return hex;
203 }
204 
224 gchar *
225 get_password_hashes (int digest_algorithm, const gchar * password)
226 {
227  gcry_error_t err = gcry_md_test_algo (digest_algorithm);
228  if (err != 0)
229  {
230  g_warning ("Could not select gcrypt algorithm: %s", gcry_strerror (err));
231  return NULL;
232  }
233 
234  g_assert (password);
235 
236  unsigned char *nonce_buffer[256];
237  guchar *seed = g_malloc0 (gcry_md_get_algo_dlen (digest_algorithm));
238  gchar *seed_hex = NULL;
239  gchar *seed_pass = NULL;
240  guchar *hash = g_malloc0 (gcry_md_get_algo_dlen (digest_algorithm));
241  gchar *hash_hex = NULL;
242  gchar *hashes_out = NULL;
243 
244  gcry_create_nonce (nonce_buffer, 256);
245  gcry_md_hash_buffer (digest_algorithm, seed, nonce_buffer, 256);
246  seed_hex = digest_hex (digest_algorithm, seed);
247  seed_pass = g_strconcat (seed_hex, password, NULL);
248  gcry_md_hash_buffer (digest_algorithm, hash, seed_pass, strlen (seed_pass));
249  hash_hex = digest_hex (digest_algorithm, hash);
250 
251  hashes_out = g_strjoin (" ", hash_hex, seed_hex, NULL);
252 
253  g_free (seed);
254  g_free (seed_hex);
255  g_free (seed_pass);
256  g_free (hash);
257  g_free (hash_hex);
258 
259  return hashes_out;
260 }
261 
271 int
272 openvas_authenticate_classic (const gchar *username, const gchar *password,
273  const gchar *hash_arg)
274 {
275  int gcrypt_algorithm = GCRY_MD_MD5; // FIX whatever configer 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 openvas_auth_init()
Initializes Gcrypt.
Definition: openvas_auth.c:115
const gchar * auth_method_name(auth_method_t method)
Return name of auth_method_t.
Definition: openvas_auth.c:102
void openvas_auth_tear_down(void)
Free memory associated to authentication configuration.
Definition: openvas_auth.c:167
#define err(x)
gchar * get_password_hashes(int digest_algorithm, const gchar *password)
Generate a pair of hashes to be used in the OpenVAS "auth/hash" file for the user.
Definition: openvas_auth.c:225
int openvas_auth_ldap_enabled()
Return whether libraries has been compiled with LDAP support.
Definition: openvas_auth.c:67
gchar * digest_hex(int gcrypt_algorithm, const guchar *digest)
Generate a hexadecimal representation of a message digest.
Definition: openvas_auth.c:184
enum authentication_method auth_method_t
Type for the numerical representation of the supported.
Definition: openvas_auth.h:50
int openvas_authenticate_classic(const gchar *username, const gchar *password, const gchar *hash_arg)
Authenticate a credential pair against openvas user file contents.
Definition: openvas_auth.c:272
int openvas_auth_radius_enabled()
Return whether libraries has been compiled with RADIUS support.
Definition: openvas_auth.c:82