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.c150
1 files changed, 115 insertions, 35 deletions
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index cc846709..93352bcc 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -28,6 +28,7 @@
28 * 28 *
29 *****************************************************************************/ 29 *****************************************************************************/
30 30
31#include "output.h"
31const char *progname = "check_radius"; 32const char *progname = "check_radius";
32const char *copyright = "2000-2024"; 33const char *copyright = "2000-2024";
33const char *email = "devel@monitoring-plugins.org"; 34const char *email = "devel@monitoring-plugins.org";
@@ -56,7 +57,8 @@ static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*arg
56static void print_help(void); 57static void print_help(void);
57void print_usage(void); 58void print_usage(void);
58 59
59#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) 60#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
61 defined(HAVE_LIBRADCLI)
60# define my_rc_conf_str(a) rc_conf_str(rch, a) 62# define my_rc_conf_str(a) rc_conf_str(rch, a)
61# if defined(HAVE_LIBRADCLI) 63# if defined(HAVE_LIBRADCLI)
62# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH) 64# define my_rc_send_server(a, b) rc_send_server(rch, a, b, AUTH)
@@ -157,50 +159,84 @@ int main(int argc, char **argv) {
157 159
158 check_radius_config config = tmp_config.config; 160 check_radius_config config = tmp_config.config;
159 161
160#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) 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)
161 rc_handle *rch = NULL; 168 rc_handle *rch = NULL;
162#endif 169#endif
163 170
171 mp_check overall = mp_check_init();
172 mp_subcheck sc_read_config = mp_subcheck_init();
173
164 char *str = strdup("dictionary"); 174 char *str = strdup("dictionary");
165 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || my_rc_read_dictionary(my_rc_conf_str(str))) { 175 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) ||
166 die(STATE_UNKNOWN, _("Config file error\n")); 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);
167 } 181 }
168 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
169 uint32_t service = PW_AUTHENTICATE_ONLY; 187 uint32_t service = PW_AUTHENTICATE_ONLY;
170 188
189 mp_subcheck sc_configuring = mp_subcheck_init();
171 SEND_DATA data; 190 SEND_DATA data;
172 memset(&data, 0, sizeof(data)); 191 memset(&data, 0, sizeof(data));
173 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && 192 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
174 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) && 193 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) &&
175 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) { 194 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) {
176 die(STATE_UNKNOWN, _("Out of Memory?\n")); 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);
177 } 199 }
178 200
179 if (config.nas_id != NULL) { 201 if (config.nas_id != NULL) {
180 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) { 202 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) {
181 die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); 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);
182 } 208 }
183 } 209 }
184 210
185 char name[HOST_NAME_MAX]; 211 char name[HOST_NAME_MAX];
186 if (config.nas_ip_address == NULL) { 212 if (config.nas_ip_address == NULL) {
187 if (gethostname(name, sizeof(name)) != 0) { 213 if (gethostname(name, sizeof(name)) != 0) {
188 die(STATE_UNKNOWN, _("gethostname() failed!\n")); 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);
189 } 218 }
190 config.nas_ip_address = name; 219 config.nas_ip_address = name;
191 } 220 }
192 221
193 struct sockaddr_storage radius_server_socket; 222 struct sockaddr_storage radius_server_socket;
194 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) { 223 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_UNSPEC)) {
195 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); 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);
196 } 228 }
197 229
198 uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr); 230 uint32_t client_id = ntohl(((struct sockaddr_in *)&radius_server_socket)->sin_addr.s_addr);
199 if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) { 231 if (my_rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) {
200 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); 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);
201 } 236 }
202 237
203 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, config.retries); 238 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval,
239 config.retries);
204 240
205#ifdef RC_BUFFER_LEN 241#ifdef RC_BUFFER_LEN
206 char msg[RC_BUFFER_LEN]; 242 char msg[RC_BUFFER_LEN];
@@ -214,50 +250,78 @@ int main(int argc, char **argv) {
214 rc_avpair_free(data.receive_pairs); 250 rc_avpair_free(data.receive_pairs);
215 } 251 }
216 252
253 mp_subcheck sc_eval = mp_subcheck_init();
254
217 if (result == TIMEOUT_RC) { 255 if (result == TIMEOUT_RC) {
218 printf("Timeout\n"); 256 xasprintf(&sc_eval.output, "timeout");
219 exit(STATE_CRITICAL); 257 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
258 mp_add_subcheck_to_check(&overall, sc_eval);
259 mp_exit(overall);
220 } 260 }
221 261
222 if (result == ERROR_RC) { 262 if (result == ERROR_RC) {
223 printf(_("Auth Error\n")); 263 xasprintf(&sc_eval.output, "auth error");
224 exit(STATE_CRITICAL); 264 sc_eval = mp_set_subcheck_state(sc_eval, STATE_CRITICAL);
265 mp_add_subcheck_to_check(&overall, sc_eval);
266 mp_exit(overall);
225 } 267 }
226 268
227 if (result == REJECT_RC) { 269 if (result == REJECT_RC) {
228 printf(_("Auth Failed\n")); 270 xasprintf(&sc_eval.output, "auth failed");
229 exit(STATE_WARNING); 271 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
272 mp_add_subcheck_to_check(&overall, sc_eval);
273 mp_exit(overall);
230 } 274 }
231 275
232 if (result == BADRESP_RC) { 276 if (result == BADRESP_RC) {
233 printf(_("Bad Response\n")); 277 xasprintf(&sc_eval.output, "bad response");
234 exit(STATE_WARNING); 278 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
279 mp_add_subcheck_to_check(&overall, sc_eval);
280 mp_exit(overall);
235 } 281 }
236 282
237 if (config.expect && !strstr(msg, config.expect)) { 283 if (config.expect && !strstr(msg, config.expect)) {
238 printf("%s\n", msg); 284 xasprintf(&sc_eval.output, "%s", msg);
239 exit(STATE_WARNING); 285 sc_eval = mp_set_subcheck_state(sc_eval, STATE_WARNING);
286 mp_add_subcheck_to_check(&overall, sc_eval);
287 mp_exit(overall);
240 } 288 }
241 289
242 if (result == OK_RC) { 290 if (result == OK_RC) {
243 printf(_("Auth OK\n")); 291 xasprintf(&sc_eval.output, "auth OK");
244 exit(STATE_OK); 292 sc_eval = mp_set_subcheck_state(sc_eval, STATE_OK);
293 mp_add_subcheck_to_check(&overall, sc_eval);
294 mp_exit(overall);
245 } 295 }
246 296
247 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); 297 xasprintf(&sc_eval.output, "unexpected result code: %d", result);
248 printf("%s\n", msg); 298 sc_eval = mp_set_subcheck_state(sc_eval, STATE_UNKNOWN);
249 exit(STATE_UNKNOWN); 299 mp_add_subcheck_to_check(&overall, sc_eval);
300
301 mp_exit(overall);
250} 302}
251 303
252/* process command-line arguments */ 304/* process command-line arguments */
253check_radius_config_wrapper process_arguments(int argc, char **argv) { 305check_radius_config_wrapper process_arguments(int argc, char **argv) {
254 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, 306 enum {
255 {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, 307 output_format_index
256 {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, 308 };
257 {"filename", required_argument, 0, 'F'}, {"expect", required_argument, 0, 'e'}, 309
258 {"retries", required_argument, 0, 'r'}, {"timeout", required_argument, 0, 't'}, 310 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'},
259 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 311 {"port", required_argument, 0, 'P'},
260 {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; 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}};
261 325
262 check_radius_config_wrapper result = { 326 check_radius_config_wrapper result = {
263 .errorcode = OK, 327 .errorcode = OK,
@@ -335,6 +399,18 @@ check_radius_config_wrapper process_arguments(int argc, char **argv) {
335 usage2(_("Timeout interval must be a positive integer"), optarg); 399 usage2(_("Timeout interval must be a positive integer"), optarg);
336 } 400 }
337 break; 401 break;
402 case output_format_index: {
403 parsed_output_format parser = mp_parse_output_format(optarg);
404 if (!parser.parsing_success) {
405 // TODO List all available formats here, maybe add anothoer usage function
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;
412 break;
413 }
338 } 414 }
339 } 415 }
340 416
@@ -388,6 +464,7 @@ void print_help(void) {
388 printf(" %s\n", _("Response string to expect from the server")); 464 printf(" %s\n", _("Response string to expect from the server"));
389 printf(" %s\n", "-r, --retries=INTEGER"); 465 printf(" %s\n", "-r, --retries=INTEGER");
390 printf(" %s\n", _("Number of times to retry a failed connection")); 466 printf(" %s\n", _("Number of times to retry a failed connection"));
467 printf(UT_OUTPUT_FORMAT);
391 468
392 printf(UT_CONN_TIMEOUT, timeout_interval); 469 printf(UT_CONN_TIMEOUT, timeout_interval);
393 470
@@ -397,9 +474,11 @@ void print_help(void) {
397 printf("%s\n", _("name and password. A configuration file must be present. The format of")); 474 printf("%s\n", _("name and password. A configuration file must be present. The format of"));
398 printf("%s\n", _("the configuration file is described in the radiusclient library sources.")); 475 printf("%s\n", _("the configuration file is described in the radiusclient library sources."));
399 printf("%s\n", _("The password option presents a substantial security issue because the")); 476 printf("%s\n", _("The password option presents a substantial security issue because the"));
400 printf("%s\n", _("password can possibly be determined by careful watching of the command line")); 477 printf("%s\n",
478 _("password can possibly be determined by careful watching of the command line"));
401 printf("%s\n", _("in a process listing. This risk is exacerbated because the plugin will")); 479 printf("%s\n", _("in a process listing. This risk is exacerbated because the plugin will"));
402 printf("%s\n", _("typically be executed at regular predictable intervals. Please be sure that")); 480 printf("%s\n",
481 _("typically be executed at regular predictable intervals. Please be sure that"));
403 printf("%s\n", _("the password used does not allow access to sensitive system resources.")); 482 printf("%s\n", _("the password used does not allow access to sensitive system resources."));
404 483
405 printf(UT_SUPPORT); 484 printf(UT_SUPPORT);
@@ -414,7 +493,8 @@ void print_usage(void) {
414} 493}
415 494
416int my_rc_read_config(char *config_file_name, rc_handle **rch) { 495int my_rc_read_config(char *config_file_name, rc_handle **rch) {
417#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) 496#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || \
497 defined(HAVE_LIBRADCLI)
418 *rch = rc_read_config(config_file_name); 498 *rch = rc_read_config(config_file_name);
419 return (rch == NULL) ? 1 : 0; 499 return (rch == NULL) ? 1 : 0;
420#else 500#else