summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-12 16:51:02 +0100
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-03-12 16:51:02 +0100
commit3008d521c1284f6f182d9cc10d56afdaa3978a04 (patch)
tree749721b13b162b01ca3b6df48129128c6de45bb5
parent0728456d73d4b3c62a2f26f4c918de571b4fbc3d (diff)
downloadmonitoring-plugins-3008d521c1284f6f182d9cc10d56afdaa3978a04.tar.gz
Refactor check_radius
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/check_radius.c126
-rw-r--r--plugins/check_radius.d/config.h42
3 files changed, 115 insertions, 54 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 6c582a15..dacd36e8 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -53,6 +53,7 @@ EXTRA_DIST = t \
53 check_ldap.d \ 53 check_ldap.d \
54 check_hpjd.d \ 54 check_hpjd.d \
55 check_game.d \ 55 check_game.d \
56 check_radius.d \
56 check_nagios.d \ 57 check_nagios.d \
57 check_dbi.d \ 58 check_dbi.d \
58 check_ssh.d \ 59 check_ssh.d \
diff --git a/plugins/check_radius.c b/plugins/check_radius.c
index ab7c6519..6a27e113 100644
--- a/plugins/check_radius.c
+++ b/plugins/check_radius.c
@@ -36,6 +36,7 @@ const char *email = "devel@monitoring-plugins.org";
36#include "utils.h" 36#include "utils.h"
37#include "netutils.h" 37#include "netutils.h"
38#include "states.h" 38#include "states.h"
39#include "check_radius.d/config.h"
39 40
40#if defined(HAVE_LIBRADCLI) 41#if defined(HAVE_LIBRADCLI)
41# include <radcli/radcli.h> 42# include <radcli/radcli.h>
@@ -47,7 +48,11 @@ const char *email = "devel@monitoring-plugins.org";
47# include <radiusclient.h> 48# include <radiusclient.h>
48#endif 49#endif
49 50
50static int process_arguments(int /*argc*/, char ** /*argv*/); 51typedef struct {
52 int errorcode;
53 check_radius_config config;
54} check_radius_config_wrapper;
55static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/);
51static void print_help(void); 56static void print_help(void);
52void print_usage(void); 57void print_usage(void);
53 58
@@ -79,21 +84,8 @@ void print_usage(void);
79# define REJECT_RC BADRESP_RC 84# define REJECT_RC BADRESP_RC
80#endif 85#endif
81 86
82static int my_rc_read_config(char * /*a*/); 87static int my_rc_read_config(char * /*a*/, rc_handle ** /*rch*/);
83 88
84#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
85static rc_handle *rch = NULL;
86#endif
87
88static char *server = NULL;
89static char *username = NULL;
90static char *password = NULL;
91static char *nasid = NULL;
92static char *nasipaddress = NULL;
93static char *expect = NULL;
94static char *config_file = NULL;
95static unsigned short port = PW_AUTH_UDP_PORT;
96static int retries = 1;
97static bool verbose = false; 89static bool verbose = false;
98 90
99/****************************************************************************** 91/******************************************************************************
@@ -157,12 +149,20 @@ int main(int argc, char **argv) {
157 /* Parse extra opts if any */ 149 /* Parse extra opts if any */
158 argv = np_extra_opts(&argc, argv, progname); 150 argv = np_extra_opts(&argc, argv, progname);
159 151
160 if (process_arguments(argc, argv) == ERROR) { 152 check_radius_config_wrapper tmp_config = process_arguments(argc, argv);
153
154 if (tmp_config.errorcode == ERROR) {
161 usage4(_("Could not parse arguments")); 155 usage4(_("Could not parse arguments"));
162 } 156 }
163 157
158 check_radius_config config = tmp_config.config;
159
160#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
161 rc_handle *rch = NULL;
162#endif
163
164 char *str = strdup("dictionary"); 164 char *str = strdup("dictionary");
165 if ((config_file && my_rc_read_config(config_file)) || my_rc_read_dictionary(my_rc_conf_str(str))) { 165 if ((config.config_file && my_rc_read_config(config.config_file, &rch)) || my_rc_read_dictionary(my_rc_conf_str(str))) {
166 die(STATE_UNKNOWN, _("Config file error\n")); 166 die(STATE_UNKNOWN, _("Config file error\n"));
167 } 167 }
168 168
@@ -171,36 +171,36 @@ int main(int argc, char **argv) {
171 SEND_DATA data; 171 SEND_DATA data;
172 memset(&data, 0, sizeof(data)); 172 memset(&data, 0, sizeof(data));
173 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) && 173 if (!(my_rc_avpair_add(&data.send_pairs, PW_SERVICE_TYPE, &service, 0) &&
174 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, username, 0) && 174 my_rc_avpair_add(&data.send_pairs, PW_USER_NAME, config.username, 0) &&
175 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, password, 0))) { 175 my_rc_avpair_add(&data.send_pairs, PW_USER_PASSWORD, config.password, 0))) {
176 die(STATE_UNKNOWN, _("Out of Memory?\n")); 176 die(STATE_UNKNOWN, _("Out of Memory?\n"));
177 } 177 }
178 178
179 if (nasid != NULL) { 179 if (config.nas_id != NULL) {
180 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, nasid, 0))) { 180 if (!(my_rc_avpair_add(&data.send_pairs, PW_NAS_IDENTIFIER, config.nas_id, 0))) {
181 die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n")); 181 die(STATE_UNKNOWN, _("Invalid NAS-Identifier\n"));
182 } 182 }
183 } 183 }
184 184
185 char name[HOST_NAME_MAX]; 185 char name[HOST_NAME_MAX];
186 if (nasipaddress == NULL) { 186 if (config.nas_ip_address == NULL) {
187 if (gethostname(name, sizeof(name)) != 0) { 187 if (gethostname(name, sizeof(name)) != 0) {
188 die(STATE_UNKNOWN, _("gethostname() failed!\n")); 188 die(STATE_UNKNOWN, _("gethostname() failed!\n"));
189 } 189 }
190 nasipaddress = name; 190 config.nas_ip_address = name;
191 } 191 }
192 192
193 struct sockaddr_storage ss; 193 struct sockaddr_storage radius_server_socket;
194 if (!dns_lookup(nasipaddress, &ss, AF_INET)) { /* TODO: Support IPv6. */ 194 if (!dns_lookup(config.nas_ip_address, &radius_server_socket, AF_INET)) { /* TODO: Support IPv6. */
195 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n")); 195 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
196 } 196 }
197 197
198 uint32_t client_id = ntohl(((struct sockaddr_in *)&ss)->sin_addr.s_addr); 198 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) { 199 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")); 200 die(STATE_UNKNOWN, _("Invalid NAS-IP-Address\n"));
201 } 201 }
202 202
203 my_rc_buildreq(&data, PW_ACCESS_REQUEST, server, port, (int)timeout_interval, retries); 203 my_rc_buildreq(&data, PW_ACCESS_REQUEST, config.server, config.port, (int)timeout_interval, config.retries);
204 204
205#ifdef RC_BUFFER_LEN 205#ifdef RC_BUFFER_LEN
206 char msg[RC_BUFFER_LEN]; 206 char msg[RC_BUFFER_LEN];
@@ -208,36 +208,49 @@ int main(int argc, char **argv) {
208 char msg[BUFFER_LEN]; 208 char msg[BUFFER_LEN];
209#endif 209#endif
210 210
211 mp_state_enum result = my_rc_send_server(&data, msg); 211 int result = my_rc_send_server(&data, msg);
212 rc_avpair_free(data.send_pairs); 212 rc_avpair_free(data.send_pairs);
213 if (data.receive_pairs) { 213 if (data.receive_pairs) {
214 rc_avpair_free(data.receive_pairs); 214 rc_avpair_free(data.receive_pairs);
215 } 215 }
216 216
217 if (result == TIMEOUT_RC) { 217 if (result == TIMEOUT_RC) {
218 die(STATE_CRITICAL, _("Timeout\n")); 218 printf("Timeout\n");
219 exit(STATE_CRITICAL);
219 } 220 }
221
220 if (result == ERROR_RC) { 222 if (result == ERROR_RC) {
221 die(STATE_CRITICAL, _("Auth Error\n")); 223 printf(_("Auth Error\n"));
224 exit(STATE_CRITICAL);
222 } 225 }
226
223 if (result == REJECT_RC) { 227 if (result == REJECT_RC) {
224 die(STATE_WARNING, _("Auth Failed\n")); 228 printf(_("Auth Failed\n"));
229 exit(STATE_WARNING);
225 } 230 }
231
226 if (result == BADRESP_RC) { 232 if (result == BADRESP_RC) {
227 die(STATE_WARNING, _("Bad Response\n")); 233 printf(_("Bad Response\n"));
234 exit(STATE_WARNING);
228 } 235 }
229 if (expect && !strstr(msg, expect)) { 236
230 die(STATE_WARNING, "%s\n", msg); 237 if (config.expect && !strstr(msg, config.expect)) {
238 printf("%s\n", msg);
239 exit(STATE_WARNING);
231 } 240 }
241
232 if (result == OK_RC) { 242 if (result == OK_RC) {
233 die(STATE_OK, _("Auth OK\n")); 243 printf(_("Auth OK\n"));
244 exit(STATE_OK);
234 } 245 }
246
235 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result); 247 (void)snprintf(msg, sizeof(msg), _("Unexpected result code %d"), result);
236 die(STATE_UNKNOWN, "%s\n", msg); 248 printf("%s\n", msg);
249 exit(STATE_UNKNOWN);
237} 250}
238 251
239/* process command-line arguments */ 252/* process command-line arguments */
240int process_arguments(int argc, char **argv) { 253check_radius_config_wrapper process_arguments(int argc, char **argv) {
241 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'}, 254 static struct option longopts[] = {{"hostname", required_argument, 0, 'H'}, {"port", required_argument, 0, 'P'},
242 {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, 255 {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'},
243 {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'}, 256 {"nas-id", required_argument, 0, 'n'}, {"nas-ip-address", required_argument, 0, 'N'},
@@ -246,6 +259,11 @@ int process_arguments(int argc, char **argv) {
246 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, 259 {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'},
247 {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; 260 {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}};
248 261
262 check_radius_config_wrapper result = {
263 .errorcode = OK,
264 .config = check_radius_config_init(),
265 };
266
249 while (true) { 267 while (true) {
250 int option = 0; 268 int option = 0;
251 int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option); 269 int option_index = getopt_long(argc, argv, "+hVvH:P:F:u:p:n:N:t:r:e:", longopts, &option);
@@ -270,20 +288,20 @@ int process_arguments(int argc, char **argv) {
270 if (!is_host(optarg)) { 288 if (!is_host(optarg)) {
271 usage2(_("Invalid hostname/address"), optarg); 289 usage2(_("Invalid hostname/address"), optarg);
272 } 290 }
273 server = optarg; 291 result.config.server = optarg;
274 break; 292 break;
275 case 'P': /* port */ 293 case 'P': /* port */
276 if (is_intnonneg(optarg)) { 294 if (is_intnonneg(optarg)) {
277 port = (unsigned short)atoi(optarg); 295 result.config.port = (unsigned short)atoi(optarg);
278 } else { 296 } else {
279 usage4(_("Port must be a positive integer")); 297 usage4(_("Port must be a positive integer"));
280 } 298 }
281 break; 299 break;
282 case 'u': /* username */ 300 case 'u': /* username */
283 username = optarg; 301 result.config.username = optarg;
284 break; 302 break;
285 case 'p': /* password */ 303 case 'p': /* password */
286 password = strdup(optarg); 304 result.config.password = strdup(optarg);
287 305
288 /* Delete the password from process list */ 306 /* Delete the password from process list */
289 while (*optarg != '\0') { 307 while (*optarg != '\0') {
@@ -292,20 +310,20 @@ int process_arguments(int argc, char **argv) {
292 } 310 }
293 break; 311 break;
294 case 'n': /* nas id */ 312 case 'n': /* nas id */
295 nasid = optarg; 313 result.config.nas_id = optarg;
296 break; 314 break;
297 case 'N': /* nas ip address */ 315 case 'N': /* nas ip address */
298 nasipaddress = optarg; 316 result.config.nas_ip_address = optarg;
299 break; 317 break;
300 case 'F': /* configuration file */ 318 case 'F': /* configuration file */
301 config_file = optarg; 319 result.config.config_file = optarg;
302 break; 320 break;
303 case 'e': /* expect */ 321 case 'e': /* expect */
304 expect = optarg; 322 result.config.expect = optarg;
305 break; 323 break;
306 case 'r': /* retries */ 324 case 'r': /* retries */
307 if (is_intpos(optarg)) { 325 if (is_intpos(optarg)) {
308 retries = atoi(optarg); 326 result.config.retries = atoi(optarg);
309 } else { 327 } else {
310 usage4(_("Number of retries must be a positive integer")); 328 usage4(_("Number of retries must be a positive integer"));
311 } 329 }
@@ -320,20 +338,20 @@ int process_arguments(int argc, char **argv) {
320 } 338 }
321 } 339 }
322 340
323 if (server == NULL) { 341 if (result.config.server == NULL) {
324 usage4(_("Hostname was not supplied")); 342 usage4(_("Hostname was not supplied"));
325 } 343 }
326 if (username == NULL) { 344 if (result.config.username == NULL) {
327 usage4(_("User not specified")); 345 usage4(_("User not specified"));
328 } 346 }
329 if (password == NULL) { 347 if (result.config.password == NULL) {
330 usage4(_("Password not specified")); 348 usage4(_("Password not specified"));
331 } 349 }
332 if (config_file == NULL) { 350 if (result.config.config_file == NULL) {
333 usage4(_("Configuration file not specified")); 351 usage4(_("Configuration file not specified"));
334 } 352 }
335 353
336 return OK; 354 return result;
337} 355}
338 356
339void print_help(void) { 357void print_help(void) {
@@ -395,11 +413,11 @@ void print_usage(void) {
395 progname); 413 progname);
396} 414}
397 415
398int my_rc_read_config(char *a) { 416int my_rc_read_config(char *config_file_name, rc_handle **rch) {
399#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI) 417#if defined(HAVE_LIBFREERADIUS_CLIENT) || defined(HAVE_LIBRADIUSCLIENT_NG) || defined(HAVE_LIBRADCLI)
400 rch = rc_read_config(a); 418 *rch = rc_read_config(config_file_name);
401 return (rch == NULL) ? 1 : 0; 419 return (rch == NULL) ? 1 : 0;
402#else 420#else
403 return rc_read_config(a); 421 return rc_read_config(config_file_name);
404#endif 422#endif
405} 423}
diff --git a/plugins/check_radius.d/config.h b/plugins/check_radius.d/config.h
new file mode 100644
index 00000000..b27d31e7
--- /dev/null
+++ b/plugins/check_radius.d/config.h
@@ -0,0 +1,42 @@
1#pragma once
2
3#include "../../config.h"
4#include <stddef.h>
5#if defined(HAVE_LIBRADCLI)
6# include <radcli/radcli.h>
7#elif defined(HAVE_LIBFREERADIUS_CLIENT)
8# include <freeradius-client.h>
9#elif defined(HAVE_LIBRADIUSCLIENT_NG)
10# include <radiusclient-ng.h>
11#else
12# include <radiusclient.h>
13#endif
14
15typedef struct {
16 char *server;
17 char *username;
18 char *password;
19 char *config_file;
20 char *nas_id;
21 char *nas_ip_address;
22 int retries;
23 unsigned short port;
24
25 char *expect;
26} check_radius_config;
27
28check_radius_config check_radius_config_init() {
29 check_radius_config tmp = {
30 .server = NULL,
31 .username = NULL,
32 .password = NULL,
33 .config_file = NULL,
34 .nas_id = NULL,
35 .nas_ip_address = NULL,
36 .retries = 1,
37 .port = PW_AUTH_UDP_PORT,
38
39 .expect = NULL,
40 };
41 return tmp;
42}