1
/******************************************************************************
3
* Program: radius server check plugin for Nagios
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.
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.
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.
22
* $Id: check_radius.c,v 1.4 2003/01/16 06:22:03 kdebisschop Exp $
24
*****************************************************************************/
26
const char *progname = "check_radius";
27
#define REVISION "$Revision: 1.4 $"
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"
34
-H host -F config_file -u username -p password\'\
35
[-P port] [-t timeout] [-r retries] [-e expect]"
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\
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\
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\
56
Show details for command-line debugging (do not use with nagios server)\n\
58
Print detailed help screen\n\
60
Print version information\n"
62
#define DESCRIPTION "\
63
This plugin tests a radius server to see if it is accepting connections.\n\
65
The server to test must be specified in the invocation, as well as a user\n\
66
name and password. A configuration file may also be present. The format of\n\
67
the configuration file is described in the radiusclient library sources.\n\
69
The password option presents a substantial security issue because the\n\
70
password can be determined by careful watching of the command line in\n\
71
a process listing. This risk is exacerbated because nagios will\n\
72
run the plugin at regular prdictable intervals. Please be sure that\n\
73
the password used does not allow access to sensitive system resources,\n\
74
otherwise compormise could occur.\n"
79
#include <radiusclient.h>
81
int process_arguments (int, char **);
82
void print_usage (void);
83
void print_help (void);
86
int port = PW_AUTH_UDP_PORT;
87
char *username = NULL;
88
char *password = NULL;
90
char *config_file = NULL;
96
/******************************************************************************
98
The (psuedo?)literate programming XML is contained within \@\@\- <XML> \-\@\@
99
tags in the comments. With in the tags, the XML is assembled sequentially.
100
You can define entities in tags. You also have all the #defines available as
103
Please note that all tags must be lowercase to use the DocBook XML DTD.
108
<title>Quick Reference</title>
109
<!-- The refentry forms a manpage -->
112
<manvolnum>5<manvolnum>
115
<refname>&progname;</refname>
116
<refpurpose>&SUMMARY;</refpurpose>
126
<title>Theory, Installation, and Operation</title>
129
<title>General Description</title>
136
<title>Future Enhancements</title>
137
<para>Todo List</para>
139
<listitem>Add option to get password from a secured file rather than the command line</listitem>
145
<title>Functions</title>
147
******************************************************************************/
150
main (int argc, char **argv)
153
char msg[BUFFER_LEN];
154
SEND_DATA data = { 0 };
158
if (process_arguments (argc, argv) == ERROR)
159
usage ("Could not parse arguments\n");
161
if ((config_file && rc_read_config (config_file)) ||
162
rc_read_dictionary (rc_conf_str ("dictionary")))
163
terminate (STATE_UNKNOWN, "Config file error");
165
service = PW_AUTHENTICATE_ONLY;
167
if (!(rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
168
rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) &&
169
rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0)))
170
terminate (STATE_UNKNOWN, "Out of Memory?");
173
* Fill in NAS-IP-Address
176
if ((client_id = rc_own_ipaddress ()) == 0)
179
if (rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) ==
180
NULL) return (ERROR_RC);
182
rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, timeout_interval,
185
result = rc_send_server (&data, msg);
186
rc_avpair_free (data.send_pairs);
187
if (data.receive_pairs)
188
rc_avpair_free (data.receive_pairs);
190
if (result == TIMEOUT_RC)
191
terminate (STATE_CRITICAL, "Timeout");
192
if (result == ERROR_RC)
193
terminate (STATE_CRITICAL, "Auth Error");
194
if (result == BADRESP_RC)
195
terminate (STATE_WARNING, "Auth Failed");
196
if (expect && !strstr (msg, expect))
197
terminate (STATE_WARNING, msg);
199
terminate (STATE_OK, "Auth OK");
205
/* process command-line arguments */
207
process_arguments (int argc, char **argv)
212
int option_index = 0;
213
static struct option long_options[] = {
214
{"hostname", required_argument, 0, 'H'},
215
{"port", required_argument, 0, 'P'},
216
{"username", required_argument, 0, 'u'},
217
{"password", required_argument, 0, 'p'},
218
{"filename", required_argument, 0, 'F'},
219
{"expect", required_argument, 0, 'e'},
220
{"retries", required_argument, 0, 'r'},
221
{"timeout", required_argument, 0, 't'},
222
{"verbose", no_argument, 0, 'v'},
223
{"version", no_argument, 0, 'V'},
224
{"help", no_argument, 0, 'h'},
233
config_file = argv[1];
236
if (is_intpos (argv[4]))
237
timeout_interval = atoi (argv[4]);
239
usage ("Timeout interval must be a positive integer");
240
if (is_intpos (argv[5]))
241
retries = atoi (argv[5]);
243
usage ("Number of retries must be a positive integer");
245
if (is_intpos (argv[7]))
246
port = atoi (argv[7]);
248
usage ("Server port must be a positive integer");
256
getopt_long (argc, argv, "+hVvH:P:F:u:p:t:r:e:", long_options,
259
c = getopt (argc, argv, "+hVvH:P:F:u:p:t:r:e:");
262
if (c == -1 || c == EOF || c == 1)
266
case '?': /* print short usage statement if args not parsable */
267
printf ("%s: Unknown argument: %s\n\n", progname, optarg);
269
exit (STATE_UNKNOWN);
273
case 'V': /* version */
274
print_revision (progname, "$Revision: 1.4 $");
276
case 'v': /* verbose mode */
279
case 'H': /* hostname */
280
if (is_host (optarg) == FALSE) {
281
printf ("Invalid host name/address\n\n");
283
exit (STATE_UNKNOWN);
288
if (is_intnonneg (optarg))
289
port = atoi (optarg);
291
usage ("Server port must be a positive integer");
293
case 'u': /* username */
296
case 'p': /* password */
299
case 'F': /* configuration file */
300
config_file = optarg;
302
case 'e': /* expect */
305
case 'r': /* retries */
306
if (is_intpos (optarg))
307
retries = atoi (optarg);
309
usage ("Number of retries must be a positive integer");
311
case 't': /* timeout */
312
if (is_intpos (optarg))
313
timeout_interval = atoi (optarg);
315
usage ("Timeout interval must be a positive integer");
327
print_revision (progname, REVISION);
329
("Copyright (c) %s %s <%s>\n\n%s\n",
330
COPYRIGHT, AUTHORS, EMAIL, SUMMARY);
333
("\nOptions:\n" LONGOPTIONS "\n" DESCRIPTION "\n",
334
port, timeout_interval);
342
printf ("Usage:\n" " %s %s\n"
344
" %s (-h | --help) for detailed help\n"
345
" %s (-V | --version) for version information\n",
347
" %s -h for detailed help\n"
348
" %s -V for version information\n",
350
progname, OPTIONS, progname, progname);