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.c631
1 files changed, 359 insertions, 272 deletions
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index 6b32710a..93352bcc 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -1,99 +1,94 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_radius plugin 3 * Monitoring check_radius plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 1999-2008 Monitoring Plugins Development Team 6 * Copyright (c) 1999-2024 Monitoring Plugins Development Team
7* 7 *
8* Description: 8 * Description:
9* 9 *
10* This file contains the check_radius plugin 10 * This file contains the check_radius plugin
11* 11 *
12* Tests to see if a radius server is accepting connections. 12 * Tests to see if a radius server is accepting connections.
13* 13 *
14* 14 *
15* This program is free software: you can redistribute it and/or modify 15 * This program is free software: you can redistribute it and/or modify
16* it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
17* the Free Software Foundation, either version 3 of the License, or 17 * the Free Software Foundation, either version 3 of the License, or
18* (at your option) any later version. 18 * (at your option) any later version.
19* 19 *
20* This program is distributed in the hope that it will be useful, 20 * This program is distributed in the hope that it will be useful,
21* but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23* GNU General Public License for more details. 23 * GNU General Public License for more details.
24* 24 *
25* You should have received a copy of the GNU General Public License 25 * You should have received a copy of the GNU General Public License
26* along with this program. If not, see <http://www.gnu.org/licenses/>. 26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27* 27 *
28* 28 *
29*****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "output.h"
31const char *progname = "check_radius"; 32const char *progname = "check_radius";
32const char *copyright = "2000-2008"; 33const char *copyright = "2000-2024";
33const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
34 35
35#include "common.h" 36#include "common.h"
36#include "utils.h" 37#include "utils.h"
37#include "netutils.h" 38#include "netutils.h"
39#include "states.h"
40#include "check_radius.d/config.h"
38 41
39#if defined(HAVE_LIBRADCLI) 42#if defined(HAVE_LIBRADCLI)
40#include <radcli/radcli.h> 43# include <radcli/radcli.h>
41#elif defined(HAVE_LIBFREERADIUS_CLIENT) 44#elif defined(HAVE_LIBFREERADIUS_CLIENT)
42#include <freeradius-client.h> 45# include <freeradius-client.h>
43#elif defined(HAVE_LIBRADIUSCLIENT_NG) 46#elif defined(HAVE_LIBRADIUSCLIENT_NG)
44#include <radiusclient-ng.h> 47# include <radiusclient-ng.h>
45#else 48#else
46#include <radiusclient.h> 49# include <radiusclient.h>
47#endif 50#endif
48 51
49int process_arguments (int, char **); 52typedef struct {
50void print_help (void); 53 int errorcode;
51void print_usage (void); 54 check_radius_config config;
52 55} check_radius_config_wrapper;
53#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) 56static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
54#define my_rc_conf_str(a) rc_conf_str(rch,a) 57static void print_help(void);
55#if defined(HAVE_LIBRADCLI) 58void print_usage(void);
56#define my_rc_send_server(a,b) rc_send_server(rch,a,b,AUTH) 59
57#else 60#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
58#define my_rc_send_server(a,b) rc_send_server(rch,a,b) 61 defined(HAVE_LIBRADCLI)
59#endif 62# define my_rc_conf_str(a) rc_conf_str(rch, a)
60#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI) 63# if defined(HAVE_LIBRADCLI)
61#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,(a)->secret,e,f) 64# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH)
65# else
66# define my_rc_send_server(a, b) rc_send_server(rch, a, b)
67# endif
68# if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADCLI)
69# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, (a)->secret, e, f)
70# else
71# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(rch, a, b, c, d, e, f)
72# endif
73# define my_rc_avpair_add(a, b, c, d) rc_avpair_add(rch, a, b, c, -1, d)
74# define my_rc_read_dictionary(a) rc_read_dictionary(rch, a)
62#else 75#else
63#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(rch,a,b,c,d,e,f) 76# define my_rc_conf_str(a) rc_conf_str(a)
64#endif 77# define my_rc_send_server(a, b) rc_send_server(a, b)
65#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(rch,a,b,c,-1,d) 78# define my_rc_buildreq(a, b, c, d, e, f) rc_buildreq(a, b, c, d, e, f)
66#define my_rc_read_dictionary(a) rc_read_dictionary(rch, a) 79# define my_rc_avpair_add(a, b, c, d) rc_avpair_add(a, b, c, d)
67#else 80# define my_rc_read_dictionary(a) rc_read_dictionary(a)
68#define my_rc_conf_str(a) rc_conf_str(a)
69#define my_rc_send_server(a,b) rc_send_server(a, b)
70#define my_rc_buildreq(a,b,c,d,e,f) rc_buildreq(a,b,c,d,e,f)
71#define my_rc_avpair_add(a,b,c,d) rc_avpair_add(a, b, c, d)
72#define my_rc_read_dictionary(a) rc_read_dictionary(a)
73#endif 81#endif
74 82
75/* REJECT_RC is only defined in some version of radiusclient. It has 83/* REJECT_RC is only defined in some version of radiusclient. It has
76 * been reported from radiusclient-ng 0.5.6 on FreeBSD 7.2-RELEASE */ 84 * been reported from radiusclient-ng 0.5.6 on FreeBSD 7.2-RELEASE */
77#ifndef REJECT_RC 85#ifndef REJECT_RC
78#define REJECT_RC BADRESP_RC 86# define REJECT_RC BADRESP_RC
79#endif 87#endif
80 88
81int my_rc_read_config(char *); 89static int my_rc_read_config(char * /*a*/, rc_handle ** /*rch*/);
82
83#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
84rc_handle *rch = NULL;
85#endif
86 90
87char *server = NULL; 91static bool verbose = false;
88char *username = NULL;
89char *password = NULL;
90char *nasid = NULL;
91char *nasipaddress = NULL;
92char *expect = NULL;
93char *config_file = NULL;
94unsigned short port = PW_AUTH_UDP_PORT;
95int retries = 1;
96bool verbose = false;
97 92
98/****************************************************************************** 93/******************************************************************************
99 94
@@ -148,149 +143,229 @@ Please note that all tags must be lowercase to use the DocBook XML DTD.
148-@@ 143-@@
149******************************************************************************/ 144******************************************************************************/
150 145
146int main(int argc, char **argv) {
147 setlocale(LC_ALL, "");
148 bindtextdomain(PACKAGE, LOCALEDIR);
149 textdomain(PACKAGE);
151 150
151 /* Parse extra opts if any */
152 argv = np_extra_opts(&argc, argv, progname);
153
154 check_radius_config_wrapper tmp_config = process_arguments(argc, argv);
155
156 if (tmp_config.errorcode == ERROR) {
157 usage4(_("Could not parse arguments"));
158 }
159
160 check_radius_config config = tmp_config.config;
161
162 if (config.output_format_is_set) {
163 mp_set_format(config.output_format);
164 }
165
166#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
167 defined(HAVE_LIBRADCLI)
168 rc_handle *rch = NULL;
169#endif
170
171 mp_check overall = mp_check_init();
172 mp_subcheck sc_read_config = mp_subcheck_init();
173
174 char *str = strdup("dictionary");
175 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) ||
176 my_rc_read_dictionary(my_rc_conf_str(str))) {
177 sc_read_config = mp_set_subcheck_state(sc_read_config, STATE_UNKNOWN);
178 xasprintf(&sc_read_config.output, "failed to read config file");
179 mp_add_subcheck_to_check(&overall, sc_read_config);
180 mp_exit(overall);
181 }
182
183 sc_read_config = mp_set_subcheck_state(sc_read_config, STATE_OK);
184 xasprintf(&sc_read_config.output, "read config file successfully");
185 mp_add_subcheck_to_check(&overall, sc_read_config);
186
187 uint32_t service = PW_AUTHENTICATE_ONLY;
188
189 mp_subcheck sc_configuring = mp_subcheck_init();
190 SEND_DATA data;
191 memset(&data, 0, sizeof(data));
192 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
193 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) &&
194 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) {
195 xasprintf(&sc_configuring.output, "Failed to the radius options: Out of Memory?");
196 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
197 mp_add_subcheck_to_check(&overall, sc_configuring);
198 mp_exit(overall);
199 }
200
201 if (config.nas_id != NULL) {
202 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) {
203 xasprintf(&sc_configuring.output,
204 "Failed to the radius options: invalid NAS identifier?");
205 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
206 mp_add_subcheck_to_check(&overall, sc_configuring);
207 mp_exit(overall);
208 }
209 }
152 210
153int
154main (int argc, char **argv)
155{
156 struct sockaddr_storage ss;
157 char name[HOST_NAME_MAX]; 211 char name[HOST_NAME_MAX];
212 if (config.nas_ip_address == NULL) {
213 if (gethostname(name, sizeof(name)) != 0) {
214 xasprintf(&sc_configuring.output, "gethostname() failed");
215 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
216 mp_add_subcheck_to_check(&overall, sc_configuring);
217 mp_exit(overall);
218 }
219 config.nas_ip_address = name;
220 }
221
222 struct sockaddr_storage radius_server_socket;
223 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) {
224 xasprintf(&sc_configuring.output, "invalid NAS IP address. Lookup failed");
225 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
226 mp_add_subcheck_to_check(&overall, sc_configuring);
227 mp_exit(overall);
228 }
229
230 uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr);
231 if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) {
232 xasprintf(&sc_configuring.output, "invalid NAS IP address. Setting option failed");
233 sc_configuring = mp_set_subcheck_state(sc_configuring, STATE_UNKNOWN);
234 mp_add_subcheck_to_check(&overall, sc_configuring);
235 mp_exit(overall);
236 }
237
238 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval,
239 config.retries);
240
158#ifdef RC_BUFFER_LEN 241#ifdef RC_BUFFER_LEN
159 char msg[RC_BUFFER_LEN]; 242 char msg[RC_BUFFER_LEN];
160#else 243#else
161 char msg[BUFFER_LEN]; 244 char msg[BUFFER_LEN];
162#endif 245#endif
163 SEND_DATA data;
164 int result = STATE_UNKNOWN;
165 uint32_t client_id, service;
166 char *str;
167 246
168 setlocale (LC_ALL, ""); 247 int result = my_rc_send_server(&data, msg);
169 bindtextdomain (PACKAGE, LOCALEDIR); 248 rc_avpair_free(data.send_pairs);
170 textdomain (PACKAGE); 249 if (data.receive_pairs) {
250 rc_avpair_free(data.receive_pairs);
251 }
171 252
172 /* Parse extra opts if any */ 253 mp_subcheck sc_eval = mp_subcheck_init();
173 argv=np_extra_opts (&argc, argv, progname);
174 254
175 if (process_arguments (argc, argv) == ERROR) 255 if (result == TIMEOUT_RC) {
176 usage4 (_("Could not parse arguments")); 256 xasprintf(&sc_eval.output, "timeout");
257 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
258 mp_add_subcheck_to_check(&overall, sc_eval);
259 mp_exit(overall);
260 }
177 261
178 str = strdup ("dictionary"); 262 if (result == ERROR_RC) {
179 if ((config_file && my_rc_read_config (config_file)) || 263 xasprintf(&sc_eval.output, "auth error");
180 my_rc_read_dictionary (my_rc_conf_str (str))) 264 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
181 die (STATE_UNKNOWN, _("Config file error\n")); 265 mp_add_subcheck_to_check(&overall, sc_eval);
266 mp_exit(overall);
267 }
182 268
183 service = PW_AUTHENTICATE_ONLY; 269 if (result == REJECT_RC) {
270 xasprintf(&sc_eval.output, "auth failed");
271 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
272 mp_add_subcheck_to_check(&overall, sc_eval);
273 mp_exit(overall);
274 }
184 275
185 memset (&data, 0, sizeof(data)); 276 if (result == BADRESP_RC) {
186 if (!(my_rc_avpair_add (&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && 277 xasprintf(&sc_eval.output, "bad response");
187 my_rc_avpair_add (&data.send_pairs, PW_USER_NAME, username, 0) && 278 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
188 my_rc_avpair_add (&data.send_pairs, PW_USER_PASSWORD, password, 0) 279 mp_add_subcheck_to_check(&overall, sc_eval);
189 )) 280 mp_exit(overall);
190 die (STATE_UNKNOWN, _("Out of Memory?\n")); 281 }
191 282
192 if (nasid != NULL) { 283 if (config.expect && !strstr(msg, config.expect)) {
193 if (!(my_rc_avpair_add (&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) 284 xasprintf(&sc_eval.output, "%s", msg);
194 die (STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); 285 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
286 mp_add_subcheck_to_check(&overall, sc_eval);
287 mp_exit(overall);
195 } 288 }
196 289
197 if (nasipaddress == NULL) { 290 if (result == OK_RC) {
198 if (gethostname (name, sizeof(name)) != 0) 291 xasprintf(&sc_eval.output, "auth OK");
199 die (STATE_UNKNOWN, _("gethostname() failed!\n")); 292 sc_eval = mp_set_subcheck_state(sc_eval, STATE_OK);
200 nasipaddress = name; 293 mp_add_subcheck_to_check(&overall, sc_eval);
294 mp_exit(overall);
201 } 295 }
202 if (!dns_lookup (nasipaddress, &ss, AF_INET)) /* TODO: Support IPv6. */
203 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
204 client_id = ntohl (((struct sockaddr_in *)&ss)->sin_addr.s_addr);
205 if (my_rc_avpair_add (&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL)
206 die (STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
207
208 my_rc_buildreq (&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval,
209 retries);
210
211 result = my_rc_send_server (&data, msg);
212 rc_avpair_free (data.send_pairs);
213 if (data.receive_pairs)
214 rc_avpair_free (data.receive_pairs);
215
216 if (result == TIMEOUT_RC)
217 die (STATE_CRITICAL, _("Timeout\n"));
218 if (result == ERROR_RC)
219 die (STATE_CRITICAL, _("Auth Error\n"));
220 if (result == REJECT_RC)
221 die (STATE_WARNING, _("Auth Failed\n"));
222 if (result == BADRESP_RC)
223 die (STATE_WARNING, _("Bad Response\n"));
224 if (expect && !strstr (msg, expect))
225 die (STATE_WARNING, "%s\n", msg);
226 if (result == OK_RC)
227 die (STATE_OK, _("Auth OK\n"));
228 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result);
229 die (STATE_UNKNOWN, "%s\n", msg);
230}
231 296
297 xasprintf(&sc_eval.output, "unexpected result code: %d", result);
298 sc_eval = mp_set_subcheck_state(sc_eval, STATE_UNKNOWN);
299 mp_add_subcheck_to_check(&overall, sc_eval);
232 300
301 mp_exit(overall);
302}
233 303
234/* process command-line arguments */ 304/* process command-line arguments */
235int 305check_radius_config_wrapper process_arguments(int argc, char **argv) {
236process_arguments (int argc, char **argv) 306 enum {
237{ 307 output_format_index
238 int c;
239
240 int option = 0;
241 static struct option longopts[] = {
242 {"hostname", required_argument, 0, 'H'},
243 {"port", required_argument, 0, 'P'},
244 {"username", required_argument, 0, 'u'},
245 {"password", required_argument, 0, 'p'},
246 {"nas-id", required_argument, 0, 'n'},
247 {"nas-ip-address", required_argument, 0, 'N'},
248 {"filename", required_argument, 0, 'F'},
249 {"expect", required_argument, 0, 'e'},
250 {"retries", required_argument, 0, 'r'},
251 {"timeout", required_argument, 0, 't'},
252 {"verbose", no_argument, 0, 'v'},
253 {"version", no_argument, 0, 'V'},
254 {"help", no_argument, 0, 'h'},
255 {0, 0, 0, 0}
256 }; 308 };
257 309
258 while (1) { 310 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
259 c = getopt_long (argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, 311 {"port", required_argument, 0, 'P'},
260 &option); 312 {"username", required_argument, 0, 'u'},
313 {"password", required_argument, 0, 'p'},
314 {"nas-id", required_argument, 0, 'n'},
315 {"nas-ip-address", required_argument, 0, 'N'},
316 {"filename", required_argument, 0, 'F'},
317 {"expect", required_argument, 0, 'e'},
318 {"retries", required_argument, 0, 'r'},
319 {"timeout", required_argument, 0, 't'},
320 {"verbose", no_argument, 0, 'v'},
321 {"version", no_argument, 0, 'V'},
322 {"help", no_argument, 0, 'h'},
323 {"output-format", required_argument, 0, output_format_index},
324 {0, 0, 0, 0}};
325
326 check_radius_config_wrapper result = {
327 .errorcode = OK,
328 .config = check_radius_config_init(),
329 };
330
331 while (true) {
332 int option = 0;
333 int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option);
261 334
262 if (c == -1 || c == EOF || c == 1) 335 if (option_index == -1 || option_index == EOF || option_index == 1) {
263 break; 336 break;
337 }
264 338
265 switch (c) { 339 switch (option_index) {
266 case '?': /* print short usage statement if args not parsable */ 340 case '?': /* print short usage statement if args not parsable */
267 usage5 (); 341 usage5();
268 case 'h': /* help */ 342 case 'h': /* help */
269 print_help (); 343 print_help();
270 exit (STATE_UNKNOWN); 344 exit(STATE_UNKNOWN);
271 case 'V': /* version */ 345 case 'V': /* version */
272 print_revision (progname, NP_VERSION); 346 print_revision(progname, NP_VERSION);
273 exit (STATE_UNKNOWN); 347 exit(STATE_UNKNOWN);
274 case 'v': /* verbose mode */ 348 case 'v': /* verbose mode */
275 verbose = true; 349 verbose = true;
276 break; 350 break;
277 case 'H': /* hostname */ 351 case 'H': /* hostname */
278 if (!is_host (optarg)) { 352 if (!is_host(optarg)) {
279 usage2 (_("Invalid hostname/address"), optarg); 353 usage2(_("Invalid hostname/address"), optarg);
280 } 354 }
281 server = optarg; 355 result.config.server = optarg;
282 break; 356 break;
283 case 'P': /* port */ 357 case 'P': /* port */
284 if (is_intnonneg (optarg)) 358 if (is_intnonneg(optarg)) {
285 port = (unsigned short)atoi (optarg); 359 result.config.port = (unsigned short)atoi(optarg);
286 else 360 } else {
287 usage4 (_("Port must be a positive integer")); 361 usage4(_("Port must be a positive integer"));
362 }
288 break; 363 break;
289 case 'u': /* username */ 364 case 'u': /* username */
290 username = optarg; 365 result.config.username = optarg;
291 break; 366 break;
292 case 'p': /* password */ 367 case 'p': /* password */
293 password = strdup(optarg); 368 result.config.password = strdup(optarg);
294 369
295 /* Delete the password from process list */ 370 /* Delete the password from process list */
296 while (*optarg != '\0') { 371 while (*optarg != '\0') {
@@ -298,119 +373,131 @@ process_arguments (int argc, char **argv)
298 optarg++; 373 optarg++;
299 } 374 }
300 break; 375 break;
301 case 'n': /* nas id */ 376 case 'n': /* nas id */
302 nasid = optarg; 377 result.config.nas_id = optarg;
303 break; 378 break;
304 case 'N': /* nas ip address */ 379 case 'N': /* nas ip address */
305 nasipaddress = optarg; 380 result.config.nas_ip_address = optarg;
306 break; 381 break;
307 case 'F': /* configuration file */ 382 case 'F': /* configuration file */
308 config_file = optarg; 383 result.config.config_file = optarg;
309 break; 384 break;
310 case 'e': /* expect */ 385 case 'e': /* expect */
311 expect = optarg; 386 result.config.expect = optarg;
312 break; 387 break;
313 case 'r': /* retries */ 388 case 'r': /* retries */
314 if (is_intpos (optarg)) 389 if (is_intpos(optarg)) {
315 retries = atoi (optarg); 390 result.config.retries = atoi(optarg);
316 else 391 } else {
317 usage4 (_("Number of retries must be a positive integer")); 392 usage4(_("Number of retries must be a positive integer"));
393 }
394 break;
395 case 't': /* timeout */
396 if (is_intpos(optarg)) {
397 timeout_interval = (unsigned)atoi(optarg);
398 } else {
399 usage2(_("Timeout interval must be a positive integer"), optarg);
400 }
318 break; 401 break;
319 case 't': /* timeout */ 402 case output_format_index: {
320 if (is_intpos (optarg)) 403 parsed_output_format parser = mp_parse_output_format(optarg);
321 timeout_interval = (unsigned)atoi (optarg); 404 if (!parser.parsing_success) {
322 else 405 // TODO List all available formats here, maybe add anothoer usage function
323 usage2 (_("Timeout interval must be a positive integer"), optarg); 406 printf("Invalid output format: %s\n", optarg);
407 exit(STATE_UNKNOWN);
408 }
409
410 result.config.output_format_is_set = true;
411 result.config.output_format = parser.output_format;
324 break; 412 break;
325 } 413 }
414 }
326 } 415 }
327 416
328 if (server == NULL) 417 if (result.config.server == NULL) {
329 usage4 (_("Hostname was not supplied")); 418 usage4(_("Hostname was not supplied"));
330 if (username == NULL) 419 }
331 usage4 (_("User not specified")); 420 if (result.config.username == NULL) {
332 if (password == NULL) 421 usage4(_("User not specified"));
333 usage4 (_("Password not specified")); 422 }
334 if (config_file == NULL) 423 if (result.config.password == NULL) {
335 usage4 (_("Configuration file not specified")); 424 usage4(_("Password not specified"));
425 }
426 if (result.config.config_file == NULL) {
427 usage4(_("Configuration file not specified"));
428 }
336 429
337 return OK; 430 return result;
338} 431}
339 432
340 433void print_help(void) {
341
342void
343print_help (void)
344{
345 char *myport; 434 char *myport;
346 xasprintf (&myport, "%d", PW_AUTH_UDP_PORT); 435 xasprintf(&myport, "%d", PW_AUTH_UDP_PORT);
347 436
348 print_revision (progname, NP_VERSION); 437 print_revision(progname, NP_VERSION);
349 438
350 printf ("Copyright (c) 1999 Robert August Vincent II\n"); 439 printf("Copyright (c) 1999 Robert August Vincent II\n");
351 printf (COPYRIGHT, copyright, email); 440 printf(COPYRIGHT, copyright, email);
352 441
353 printf("%s\n", _("Tests to see if a RADIUS server is accepting connections.")); 442 printf("%s\n", _("Tests to see if a RADIUS server is accepting connections."));
354 443
355 printf ("\n\n"); 444 printf("\n\n");
356 445
357 print_usage (); 446 print_usage();
358 447
359 printf (UT_HELP_VRSN); 448 printf(UT_HELP_VRSN);
360 printf (UT_EXTRA_OPTS); 449 printf(UT_EXTRA_OPTS);
361 450
362 printf (UT_HOST_PORT, 'P', myport); 451 printf(UT_HOST_PORT, 'P', myport);
363 452
364 printf (" %s\n", "-u, --username=STRING"); 453 printf(" %s\n", "-u, --username=STRING");
365 printf (" %s\n", _("The user to authenticate")); 454 printf(" %s\n", _("The user to authenticate"));
366 printf (" %s\n", "-p, --password=STRING"); 455 printf(" %s\n", "-p, --password=STRING");
367 printf (" %s\n", _("Password for authentication (SECURITY RISK)")); 456 printf(" %s\n", _("Password for authentication (SECURITY RISK)"));
368 printf (" %s\n", "-n, --nas-id=STRING"); 457 printf(" %s\n", "-n, --nas-id=STRING");
369 printf (" %s\n", _("NAS identifier")); 458 printf(" %s\n", _("NAS identifier"));
370 printf (" %s\n", "-N, --nas-ip-address=STRING"); 459 printf(" %s\n", "-N, --nas-ip-address=STRING");
371 printf (" %s\n", _("NAS IP Address")); 460 printf(" %s\n", _("NAS IP Address"));
372 printf (" %s\n", "-F, --filename=STRING"); 461 printf(" %s\n", "-F, --filename=STRING");
373 printf (" %s\n", _("Configuration file")); 462 printf(" %s\n", _("Configuration file"));
374 printf (" %s\n", "-e, --expect=STRING"); 463 printf(" %s\n", "-e, --expect=STRING");
375 printf (" %s\n", _("Response string to expect from the server")); 464 printf(" %s\n", _("Response string to expect from the server"));
376 printf (" %s\n", "-r, --retries=INTEGER"); 465 printf(" %s\n", "-r, --retries=INTEGER");
377 printf (" %s\n", _("Number of times to retry a failed connection")); 466 printf(" %s\n", _("Number of times to retry a failed connection"));
378 467 printf(UT_OUTPUT_FORMAT);
379 printf (UT_CONN_TIMEOUT, timeout_interval); 468
380 469 printf(UT_CONN_TIMEOUT, timeout_interval);
381 printf ("\n"); 470
382 printf ("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections.")); 471 printf("\n");
383 printf ("%s\n", _("The server to test must be specified in the invocation, as well as a user")); 472 printf("%s\n", _("This plugin tests a RADIUS server to see if it is accepting connections."));
384 printf ("%s\n", _("name and password. A configuration file must be present. The format of")); 473 printf("%s\n", _("The server to test must be specified in the invocation, as well as a user"));
385 printf ("%s\n", _("the configuration file is described in the radiusclient library sources.")); 474 printf("%s\n", _("name and password. A configuration file must be present. The format of"));
386 printf ("%s\n", _("The password option presents a substantial security issue because the")); 475 printf("%s\n", _("the configuration file is described in the radiusclient library sources."));
387 printf ("%s\n", _("password can possibly be determined by careful watching of the command line")); 476 printf("%s\n", _("The password option presents a substantial security issue because the"));
388 printf ("%s\n", _("in a process listing. This risk is exacerbated because the plugin will")); 477 printf("%s\n",
389 printf ("%s\n", _("typically be executed at regular predictable intervals. Please be sure that")); 478 _("password can possibly be determined by careful watching of the command line"));
390 printf ("%s\n", _("the password used does not allow access to sensitive system resources.")); 479 printf("%s\n", _("in a process listing. This risk is exacerbated because the plugin will"));
391 480 printf("%s\n",
392 printf (UT_SUPPORT); 481 _("typically be executed at regular predictable intervals. Please be sure that"));
482 printf("%s\n", _("the password used does not allow access to sensitive system resources."));
483
484 printf(UT_SUPPORT);
393} 485}
394 486
395 487void print_usage(void) {
396 488 printf("%s\n", _("Usage:"));
397void 489 printf("%s -H host -F config_file -u username -p password\n\
398print_usage (void)
399{
400 printf ("%s\n", _("Usage:"));
401 printf ("%s -H host -F config_file -u username -p password\n\
402 [-P port] [-t timeout] [-r retries] [-e expect]\n\ 490 [-P port] [-t timeout] [-r retries] [-e expect]\n\
403 [-n nas-id] [-N nas-ip-addr]\n", progname); 491 [-n nas-id] [-N nas-ip-addr]\n",
492 progname);
404} 493}
405 494
406 495int my_rc_read_config(char *config_file_name, rc_handle **rch) {
407 496#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
408int my_rc_read_config(char * a) 497 defined(HAVE_LIBRADCLI)
409{ 498 *rch = rc_read_config(config_file_name);
410#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
411 rch = rc_read_config(a);
412 return (rch == NULL) ? 1 : 0; 499 return (rch == NULL) ? 1 : 0;
413#else 500#else
414 return rc_read_config(a); 501 return rc_read_config(config_file_name);
415#endif 502#endif
416} 503}