OpenVAS Libraries  9.0.3
radius.c
Go to the documentation of this file.
1 /* openvas-libraries/nasl
2  * $Id$
3  * Description: Implementation of an API for Radius authentication.
4  *
5  * Authors:
6  * Hani Benhabiles <hani.benhabiles@greenbone.net>
7  *
8  * Copyright:
9  * Copyright (C) 2015 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #ifdef ENABLE_RADIUS_AUTH
27 
28 #if defined(RADIUS_AUTH_FREERADIUS)
29 #include <freeradius-client.h>
30 #ifndef RC_CONFIG_FILE
31 #define RC_DICTIONARY_FILE "/etc/radiusclient/dictionary"
32 #endif
33 #elif defined(RADIUS_AUTH_RADCLI)
34 #include <unistd.h>
35 #include <radcli/radcli.h>
36 #ifndef RC_CONFIG_FILE
37 #define RC_DICTIONARY_FILE "/etc/radcli/dictionary"
38 #endif
39 #endif
40 
41 #include "../base/openvas_networking.h"
42 #include <glib.h>
43 
44 #ifndef PW_MAX_MSG_SIZE
45 #define PW_MAX_MSG_SIZE 4096
46 #endif
47 
56 static rc_handle *
57 radius_init (const char *hostname, const char *secret)
58 {
59  rc_handle *rh;
60  char authserver[4096];
61  struct sockaddr_in6 ip6;
62 
63  rh = NULL;
64 
65  if (inet_pton (AF_INET6, hostname, &(ip6.sin6_addr)) == 1)
66  snprintf (authserver, sizeof (authserver), "[%s]::%s", hostname, secret);
67  else
68  snprintf (authserver, sizeof (authserver), "%s::%s", hostname, secret);
69 
70 #if defined(RADIUS_AUTH_RADCLI)
71  // Create config from file for older radcli versions
72  FILE *config_file = NULL;
73  char config_filename[35] = "/tmp/openvas_radius_conf_XXXXXX";
74  int config_fd = mkstemp (config_filename);
75 
76  if (config_fd == -1)
77  {
78  g_warning ("%s: Couldn't create temp radius config file: %s\n",
79  __FUNCTION__, strerror (errno));
80  goto radius_init_fail;
81  }
82 
83  config_file = fdopen (config_fd, "w");
84  if (config_file == NULL)
85  {
86  close (config_fd);
87  g_warning ("%s: Couldn't open temp radius config file %s: %s\n",
88  __FUNCTION__, config_filename, strerror (errno));
89  goto radius_init_fail;
90  }
91 
92  if (fprintf (config_file,
93  "auth_order radius\n"
94  "login_tries 4\n"
95  "dictionary %s\n"
96  "seqfile /var/run/radius.seq\n"
97  "radius_retries 3\n"
98  "radius_timeout 5\n"
99  "radius_deadtime 0\n"
100  "authserver %s\n"
101  "acctserver %s\n",
102  RC_DICTIONARY_FILE,
103  authserver,
104  authserver) < 0)
105  {
106  fclose (config_file);
107  g_warning ("%s: Couldn't write to temp radius config file %s:%s\n",
108  __FUNCTION__, config_filename, strerror (errno));
109  unlink (config_filename);
110  goto radius_init_fail;
111  }
112  fclose (config_file);
113 
114  rh = rc_read_config (config_filename);
115  if (rh == NULL)
116  {
117  g_warning ("%s: Couldn't read temp radius config file %s\n",
118  __FUNCTION__, config_filename);
119  unlink (config_filename);
120  goto radius_init_fail;
121  }
122  unlink (config_filename);
123 #else // defined(RADIUS_AUTH_RADCLI)
124  if ((rh = rc_new ()) == NULL)
125  {
126  g_warning ("radius_init: Couldn't allocate memory");
127  return NULL;
128  }
129  if (!rc_config_init (rh))
130  {
131  g_warning("radius_init: Couldn't initialize the config");
132  return NULL;
133  }
134 
135  /* Set the basic configuration options. */
136  if (rc_add_config (rh, "auth_order", "radius", "config", 0))
137  {
138  g_warning("radius_init: Couldn't set auth_order");
139  goto radius_init_fail;
140  }
141  if (rc_add_config (rh, "login_tries", "4", "config", 0))
142  {
143  g_warning("radius_init: Couldn't set login_tries");
144  goto radius_init_fail;
145  }
146  if (rc_add_config (rh, "dictionary", RC_DICTIONARY_FILE, "config", 0))
147  {
148  g_warning("radius_init: Couldn't set dictionary");
149  goto radius_init_fail;
150  }
151  if (rc_add_config (rh, "seqfile", "/var/run/radius.seq", "config", 0))
152  {
153  g_warning("radius_init: Couldn't set seqfile");
154  goto radius_init_fail;
155  }
156  if (rc_add_config (rh, "radius_retries", "3", "config", 0))
157  {
158  g_warning("radius_init: Couldn't set radius_retries");
159  goto radius_init_fail;
160  }
161  if (rc_add_config (rh, "radius_timeout", "5", "config", 0))
162  {
163  g_warning("radius_init: Couldn't set radius_timeout");
164  goto radius_init_fail;
165  }
166  if (rc_add_config (rh, "radius_deadtime", "0", "config", 0))
167  {
168  g_warning("radius_init: Couldn't set radius_deadtime");
169  goto radius_init_fail;
170  }
171  if (rc_add_config (rh, "authserver", authserver, "config", 0) != 0)
172  {
173  g_warning ("radius_init: Couldn't set authserver %s", authserver);
174  goto radius_init_fail;
175  }
176  if (rc_read_dictionary (rh, RC_DICTIONARY_FILE) != 0)
177  {
178  g_warning ("radius_init: Couldn't read the dictionary file %s",
179  RC_DICTIONARY_FILE);
180  goto radius_init_fail;
181  }
182 #endif // defined(RADIUS_AUTH_RADCLI)
183 
184  return rh;
185 
186 radius_init_fail:
187  rc_destroy (rh);
188  return NULL;
189 }
190 
201 int
202 radius_authenticate (const char *hostname, const char *secret,
203  const char *username, const char *password)
204 {
205  uint32_t service = PW_AUTHENTICATE_ONLY;
206  char msg[PW_MAX_MSG_SIZE];
207  VALUE_PAIR *send = NULL, *received = NULL;
208  rc_handle *rh;
209  int rc = -1;
210  struct sockaddr_in ip4;
211  struct sockaddr_in6 ip6;
212 
213  rh = radius_init (hostname, secret);
214  if (!rh)
215  return -1;
216  if (rc_avpair_add (rh, &send, PW_USER_NAME, (char *) username, -1, 0) == NULL)
217  {
218  g_warning ("radius_authenticate: Couldn't set the username");
219  goto authenticate_leave;
220  }
221  if (rc_avpair_add (rh, &send, PW_USER_PASSWORD, (char *) password, -1, 0)
222  == NULL)
223  {
224  g_warning ("radius_authenticate: Couldn't set the password");
225  goto authenticate_leave;
226  }
227  if (rc_avpair_add (rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
228  {
229  g_warning ("radius_authenticate: Couldn't set the service type");
230  goto authenticate_leave;
231  }
232  if (openvas_resolve (hostname, &ip4, AF_INET)
233  && openvas_resolve (hostname, &ip6, AF_INET6))
234  {
235  g_warning ("radius_authenticate: Couldn't resolve %s", hostname);
236  goto authenticate_leave;
237  }
238 
239  rc = 1;
240  if (rc_auth (rh, 0, send, &received, msg) == OK_RC)
241  rc = 0;
242 
243 authenticate_leave:
244  rc_destroy (rh);
245  if (send)
246  rc_avpair_free (send);
247  if (received)
248  rc_avpair_free (received);
249  return rc;
250 }
251 
252 #else /* ENABLE_RADIUS_AUTH */
253 
264 int
265 radius_authenticate (const char *hostname, const char *secret,
266  const char *username, const char *password)
267 {
268  (void) hostname;
269  (void) secret;
270  (void) username;
271  (void) password;
272 
273  return -1;
274 }
275 
276 #endif /* ENABLE_RADIUS_AUTH */
int radius_authenticate(const char *hostname, const char *secret, const char *username, const char *password)
Dummy function for manager.
Definition: radius.c:265
int openvas_resolve(const char *name, void *dst, int family)
Resolves a hostname to an IPv4 or IPv6 address.