diff options
author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-03-12 16:51:02 +0100 |
---|---|---|
committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-03-12 16:51:02 +0100 |
commit | 3008d521c1284f6f182d9cc10d56afdaa3978a04 (patch) | |
tree | 749721b13b162b01ca3b6df48129128c6de45bb5 /plugins | |
parent | 0728456d73d4b3c62a2f26f4c918de571b4fbc3d (diff) | |
download | monitoring-plugins-3008d521c1284f6f182d9cc10d56afdaa3978a04.tar.gz |
Refactor check_radius
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/check_radius.c | 126 | ||||
-rw-r--r-- | plugins/check_radius.d/config.h | 42 |
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 | ||
50 | static int process_arguments(int /*argc*/, char ** /*argv*/); | 51 | typedef struct { |
52 | int errorcode; | ||
53 | check_radius_config config; | ||
54 | } check_radius_config_wrapper; | ||
55 | static check_radius_config_wrapper process_arguments(int /*argc*/, char ** /*argv*/); | ||
51 | static void print_help(void); | 56 | static void print_help(void); |
52 | void print_usage(void); | 57 | void 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 | ||
82 | static int my_rc_read_config(char * /*a*/); | 87 | static 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) | ||
85 | static rc_handle *rch = NULL; | ||
86 | #endif | ||
87 | |||
88 | static char *server = NULL; | ||
89 | static char *username = NULL; | ||
90 | static char *password = NULL; | ||
91 | static char *nasid = NULL; | ||
92 | static char *nasipaddress = NULL; | ||
93 | static char *expect = NULL; | ||
94 | static char *config_file = NULL; | ||
95 | static unsigned short port = PW_AUTH_UDP_PORT; | ||
96 | static int retries = 1; | ||
97 | static bool verbose = false; | 89 | static 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 */ |
240 | int process_arguments(int argc, char **argv) { | 253 | check_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 | ||
339 | void print_help(void) { | 357 | void print_help(void) { |
@@ -395,11 +413,11 @@ void print_usage(void) { | |||
395 | progname); | 413 | progname); |
396 | } | 414 | } |
397 | 415 | ||
398 | int my_rc_read_config(char *a) { | 416 | int 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 | |||
15 | typedef 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 | |||
28 | check_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 | } | ||