summaryrefslogtreecommitdiffstats
path: root/plugins/check_radius.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_radius.c')
-rw-r--r--plugins/check_radius.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
new file mode 100644
index 00000000..614d467b
--- /dev/null
+++ b/plugins/check_radius.c
@@ -0,0 +1,345 @@
1/******************************************************************************
2 *
3 * Program: radius server check plugin for Nagios
4 * License: GPL
5 *
6 * License Information:
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * $Id$
23 *
24 *****************************************************************************/
25
26#define PROGNAME "check_radius"
27#define REVISION "$Revision$"
28#define COPYRIGHT "1999-2001"
29#define AUTHORS "Robert August Vincent II/Karl DeBisschop"
30#define EMAIL "kdebisschop@users.sourceforge.net"
31#define SUMMARY "Tests to see if a radius server is accepting connections.\n"
32
33#define OPTIONS "\
34-H host -F config_file -u username -p password\'\
35 [-P port] [-t timeout] [-r retries] [-e expect]"
36
37#define LONGOPTIONS "\
38 -H, --hostname=HOST\n\
39 Host name argument for servers using host headers (use numeric\n\
40 address if possible to bypass DNS lookup).\n\
41 -P, --port=INTEGER\n\
42 Port number (default: %d)\n\
43 -u, --username=STRING\n\
44 The user to authenticate\n\
45 -p, --password=STRING\n\
46 Password for autentication (SECURITY RISK)\n\
47 -F, --filename=STRING\n\
48 Configuration file\n\
49 -e, --expect=STRING\n\
50 Response string to expect from the server\n\
51 -r, --retries=INTEGER\n\
52 Number of times to retry a failed connection\n\
53 -t, --timeout=INTEGER\n\
54 Seconds before connection times out (default: %d)\n\
55 -v\n\
56 Show details for command-line debugging (do not use with nagios server)\n\
57 -h, --help\n\
58 Print detailed help screen\n\
59 -V, --version\n\
60 Print version information\n"
61
62#define DESCRIPTION "\
63The password option presents a substantial security issue because the
64password can be determined by careful watching of the command line in
65a process listing. This risk is exacerbated because nagios will
66run the plugin at regular prdictable intervals. Please be sure that
67the password used does not allow access to sensitive system resources,
68otherwise compormise could occur.\n"
69
70#include "config.h"
71#include "common.h"
72#include "utils.h"
73#include <radiusclient.h>
74
75int process_arguments (int, char **);
76void print_usage (void);
77void print_help (void);
78
79char *server = NULL;
80int port = PW_AUTH_UDP_PORT;
81char *username = NULL;
82char *password = NULL;
83char *expect = NULL;
84char *config_file = NULL;
85int retries = 1;
86int verbose = FALSE;
87
88ENV *env = NULL;
89
90/******************************************************************************
91
92The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
93tags in the comments. With in the tags, the XML is assembled sequentially.
94You can define entities in tags. You also have all the #defines available as
95entities.
96
97Please note that all tags must be lowercase to use the DocBook XML DTD.
98
99@@-<article>
100
101<sect1>
102<title>Quick Reference</title>
103<!-- The refentry forms a manpage -->
104<refentry>
105<refmeta>
106<manvolnum>5<manvolnum>
107</refmeta>
108<refnamdiv>
109<refname>&PROGNAME;</refname>
110<refpurpose>&SUMMARY;</refpurpose>
111</refnamdiv>
112</refentry>
113</sect1>
114
115<sect1>
116<title>FAQ</title>
117</sect1>
118
119<sect1>
120<title>Theory, Installation, and Operation</title>
121
122<sect2>
123<title>General Description</title>
124<para>
125&DESCRIPTION;
126</para>
127</sect2>
128
129<sect2>
130<title>Future Enhancements</title>
131<para>ToDo List</para>
132<itemizedlist>
133<listitem>Add option to get password from a secured file rather than the command line</listitem>
134</itemizedlist>
135</sect2>
136
137
138<sect2>
139<title>Functions</title>
140-@@
141******************************************************************************/
142
143int
144main (int argc, char **argv)
145{
146 UINT4 service;
147 char msg[BUFFER_LEN];
148 SEND_DATA data = { 0 };
149 int result;
150 UINT4 client_id;
151
152 if (process_arguments (argc, argv) == ERROR)
153 usage ("Could not parse arguments\n");
154
155 if ((config_file && rc_read_config (config_file)) ||
156 rc_read_dictionary (rc_conf_str ("dictionary")))
157 terminate (STATE_UNKNOWN, "Config file error");
158
159 service = PW_AUTHENTICATE_ONLY;
160
161 if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
162 rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
163 rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0)))
164 terminate (STATE_UNKNOWN, "Out of Memory?");
165
166 /*
167 * Fill in NAS-IP-Address
168 */
169
170 if ((client_id = rc_own_ipaddress ()) == 0)
171 return (ERROR_RC);
172
173 if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) ==
174 NULL) return (ERROR_RC);
175
176 rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, timeout_interval,
177 retries);
178
179 result = rc_send_server (&data, msg);
180 rc_avpair_free (data.send_pairs);
181 if (data.receive_pairs)
182 rc_avpair_free (data.receive_pairs);
183
184 if (result == TIMEOUT_RC)
185 terminate (STATE_CRITICAL, "Timeout");
186 if (result == ERROR_RC)
187 terminate (STATE_CRITICAL, "Auth Error");
188 if (result == BADRESP_RC)
189 terminate (STATE_WARNING, "Auth Failed");
190 if (expect && !strstr (msg, expect))
191 terminate (STATE_WARNING, msg);
192 if (result == OK_RC)
193 terminate (STATE_OK, "Auth OK");
194 return (0);
195}
196
197
198
199/* process command-line arguments */
200int
201process_arguments (int argc, char **argv)
202{
203 int c;
204
205#ifdef HAVE_GETOPT_H
206 int option_index = 0;
207 static struct option long_options[] = {
208 {"hostname", required_argument, 0, 'H'},
209 {"port", required_argument, 0, 'P'},
210 {"username", required_argument, 0, 'u'},
211 {"password", required_argument, 0, 'p'},
212 {"filename", required_argument, 0, 'F'},
213 {"expect", required_argument, 0, 'e'},
214 {"retries", required_argument, 0, 'r'},
215 {"timeout", required_argument, 0, 't'},
216 {"verbose", no_argument, 0, 'v'},
217 {"version", no_argument, 0, 'V'},
218 {"help", no_argument, 0, 'h'},
219 {0, 0, 0, 0}
220 };
221#endif
222
223 if (argc < 2)
224 return ERROR;
225
226 if (argc == 9) {
227 config_file = argv[1];
228 username = argv[2];
229 password = argv[3];
230 if (is_intpos (argv[4]))
231 timeout_interval = atoi (argv[4]);
232 else
233 usage ("Timeout interval must be a positive integer");
234 if (is_intpos (argv[5]))
235 retries = atoi (argv[5]);
236 else
237 usage ("Number of retries must be a positive integer");
238 server = argv[6];
239 if (is_intpos (argv[7]))
240 port = atoi (argv[7]);
241 else
242 usage ("Server port must be a positive integer");
243 expect = argv[8];
244 return OK;
245 }
246
247 while (1) {
248#ifdef HAVE_GETOPT_H
249 c =
250 getopt_long (argc, argv, "+hVvH:P:F:u:p:t:r:e:", long_options,
251 &option_index);
252#else
253 c = getopt (argc, argv, "+hVvH:P:F:u:p:t:r:e:");
254#endif
255
256 if (c == -1 || c == EOF || c == 1)
257 break;
258
259 switch (c) {
260 case '?': /* print short usage statement if args not parsable */
261 printf ("%s: Unknown argument: %s\n\n", my_basename (argv[0]), optarg);
262 print_usage ();
263 exit (STATE_UNKNOWN);
264 case 'h': /* help */
265 print_help ();
266 exit (OK);
267 case 'V': /* version */
268 print_revision (my_basename (argv[0]), "$Revision$");
269 exit (OK);
270 case 'v': /* verbose mode */
271 verbose = TRUE;
272 break;
273 case 'H': /* hostname */
274 if (is_host (optarg) == FALSE) {
275 printf ("Invalid host name/address\n\n");
276 print_usage ();
277 exit (STATE_UNKNOWN);
278 }
279 server = optarg;
280 break;
281 case 'P': /* port */
282 if (is_intnonneg (optarg))
283 port = atoi (optarg);
284 else
285 usage ("Server port must be a positive integer");
286 break;
287 case 'u': /* username */
288 username = optarg;
289 break;
290 case 'p': /* password */
291 password = optarg;
292 break;
293 case 'F': /* configuration file */
294 config_file = optarg;
295 break;
296 case 'e': /* expect */
297 expect = optarg;
298 break;
299 case 'r': /* retries */
300 if (is_intpos (optarg))
301 retries = atoi (optarg);
302 else
303 usage ("Number of retries must be a positive integer");
304 break;
305 case 't': /* timeout */
306 if (is_intpos (optarg))
307 timeout_interval = atoi (optarg);
308 else
309 usage ("Timeout interval must be a positive integer");
310 break;
311 }
312 }
313 return OK;
314}
315
316
317
318void
319print_help (void)
320{
321 print_revision (PROGNAME, REVISION);
322 printf
323 ("Copyright (c) %s %s <%s>\n\n%s\n",
324 COPYRIGHT, AUTHORS, EMAIL, SUMMARY);
325 print_usage ();
326 printf
327 ("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
328 port, timeout_interval);
329 support ();
330}
331
332
333void
334print_usage (void)
335{
336 printf ("Usage:\n" " %s %s\n"
337#ifdef HAVE_GETOPT_H
338 " %s (-h | --help) for detailed help\n"
339 " %s (-V | --version) for version information\n",
340#else
341 " %s -h for detailed help\n"
342 " %s -V for version information\n",
343#endif
344 PROGNAME, OPTIONS, PROGNAME, PROGNAME);
345}