1 /****************************************************************************
2 *
3 * nrpe.c - Nagios Remote Plugin Executor
4 *
5 * License: GPLv2
6 * Copyright (c) 2009-2017 Nagios Enterprises
7 * 1999-2008 Ethan Galstad (nagios@nagios.org)
8 *
9 * Command line: nrpe -c <config_file> [--inetd | --daemon]
10 *
11 * Description:
12 *
13 * This program is designed to run as a background process and
14 * handle incoming requests (from the host running Nagios) for
15 * plugin execution. It is useful for running "local" plugins
16 * such as check_users, check_load, check_disk, etc. without
17 * having to use rsh or ssh.
18 *
19 * License Notice:
20 *
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 2 of the License, or
24 * (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, write to the Free Software
33 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 *
35 ****************************************************************************/
36
37 #include "config.h"
38 #include "common.h"
39 #include "nrpe.h"
40 #include "utils.h"
41 #include "acl.h"
42
43 #ifdef HAVE_SSL
44 # ifdef USE_SSL_DH
45 # include "../include/dh.h"
46 # endif
47 #endif
48 #ifndef HAVE_ASPRINTF
49 extern int asprintf(char **ptr, const char *format, ...);
50 #endif
51
52 #ifdef HAVE_LIBWRAP
53 int allow_severity = LOG_INFO;
54 int deny_severity = LOG_WARNING;
55 # ifndef HAVE_RFC931_TIMEOUT
56 int rfc931_timeout=15;
57 # endif
58 #endif
59
60 #ifdef HAVE_SSL
61 # if (defined(__sun) && defined(SOLARIS_10)) || defined(_AIX) || defined(__hpux)
62 SSL_METHOD *meth;
63 # else
64 const SSL_METHOD *meth;
65 # endif
66 SSL_CTX *ctx;
67 int use_ssl = TRUE;
68 #else
69 int use_ssl = FALSE;
70 #endif
71
72 #define DEFAULT_COMMAND_TIMEOUT 60 /* default timeout for execution of plugins */
73 #define MAXFD 64
74 #define NASTY_METACHARS "|`&><'\\[]{};\r\n"
75 #define MAX_LISTEN_SOCKS 16
76 #define DEFAULT_LISTEN_QUEUE_SIZE 5
77 #define DEFAULT_SSL_SHUTDOWN_TIMEOUT 15
78
79 #define how_many(x,y) (((x)+((y)-1))/(y))
80
81 extern int errno;
82 struct addrinfo *listen_addrs = NULL;
83 int listen_socks[MAX_LISTEN_SOCKS];
84 char remote_host[MAX_HOST_ADDRESS_LENGTH];
85 char *macro_argv[MAX_COMMAND_ARGUMENTS];
86 char config_file[MAX_INPUT_BUFFER] = "nrpe.cfg";
87 char server_address[NI_MAXHOST] = "";
88 char *command_name = NULL;
89 int log_facility = LOG_DAEMON;
90 int server_port = DEFAULT_SERVER_PORT;
91 int num_listen_socks = 0;
92 int address_family = AF_UNSPEC;
93 int socket_timeout = DEFAULT_SOCKET_TIMEOUT;
94 int command_timeout = DEFAULT_COMMAND_TIMEOUT;
95 int connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
96 int ssl_shutdown_timeout = DEFAULT_SSL_SHUTDOWN_TIMEOUT;
97 char *command_prefix = NULL;
98 int packet_ver = 0;
99 command *command_list = NULL;
100 char *nrpe_user = NULL;
101 char *nrpe_group = NULL;
102 char *allowed_hosts = NULL;
103 char *keep_env_vars = NULL;
104 char *pid_file = NULL;
105 int wrote_pid_file = FALSE;
106 int allow_arguments = FALSE;
107 int allow_bash_cmd_subst = FALSE;
108 int allow_weak_random_seed = FALSE;
109 int sigrestart = FALSE;
110 int sigshutdown = FALSE;
111 int show_help = FALSE;
112 int show_license = FALSE;
113 int show_version = FALSE;
114 int use_inetd = TRUE;
115 int commands_running = 0;
116 int max_commands = 0;
117 int debug = FALSE;
118 int use_src = FALSE; /* Define parameter for SRC option */
119 int no_forking = FALSE;
120 int listen_queue_size = DEFAULT_LISTEN_QUEUE_SIZE;
121 char *nasty_metachars = NULL;
122 extern char *log_file;
123
124 /* SSL/TLS parameters */
125 typedef enum _SSL_VER {
126 SSLv2 = 1, SSLv2_plus, SSLv3, SSLv3_plus, TLSv1,
127 TLSv1_plus, TLSv1_1, TLSv1_1_plus, TLSv1_2, TLSv1_2_plus
128 } SslVer;
129
130 typedef enum _CLNT_CERTS {
131 ClntCerts_Unknown = 0, Ask_For_Cert = 1, Require_Cert = 2
132 } ClntCerts;
133
134 typedef enum _SSL_LOGGING {
135 SSL_NoLogging = 0, SSL_LogStartup = 1, SSL_LogIpAddr = 2,
136 SSL_LogVersion = 4, SSL_LogCipher = 8, SSL_LogIfClientCert = 16,
137 SSL_LogCertDetails = 32
138 } SslLogging;
139
140 struct _SSL_PARMS {
141 char *cert_file;
142 char *cacert_file;
143 char *privatekey_file;
144 char cipher_list[MAX_FILENAME_LENGTH];
145 SslVer ssl_proto_ver;
146 int allowDH;
147 ClntCerts client_certs;
148 SslLogging log_opts;
149 } sslprm = {
150 #if OPENSSL_VERSION_NUMBER >= 0x10100000
151 NULL, NULL, NULL, "ALL:!MD5:@STRENGTH:@SECLEVEL=0", TLSv1_plus, TRUE, 0, SSL_NoLogging};
152 #else
153 NULL, NULL, NULL, "ALL:!MD5:@STRENGTH", TLSv1_plus, TRUE, 0, SSL_NoLogging};
154 #endif
155
156
157 #ifdef HAVE_SSL
158 static int verify_callback(int ok, X509_STORE_CTX * ctx);
159 static void my_disconnect_sighandler(int sig);
160 static void complete_SSL_shutdown(SSL *);
161 #endif
162
main(int argc,char ** argv)163 int main(int argc, char **argv)
164 {
165 int result = OK;
166 int x;
167 uint32_t y;
168 char buffer[MAX_INPUT_BUFFER];
169
170 init();
171
172 /* process command-line args */
173 result = process_arguments(argc, argv);
174 if (result != OK || show_help == TRUE || show_license == TRUE || show_version == TRUE)
175 usage(result);
176
177 /* make sure the config file uses an absolute path */
178 if (config_file[0] != '/') {
179
180 /* save the name of the config file */
181 strncpy(buffer, config_file, sizeof(buffer));
182 buffer[sizeof(buffer) - 1] = '\x0';
183
184 /* get absolute path of current working directory */
185 strcpy(config_file, "");
186 if (getcwd(config_file, sizeof(config_file)) == NULL) {
187 printf("ERROR: getcwd(): %s, bailing out...\n", strerror(errno));
188 exit(STATE_CRITICAL);
189 }
190
191 /* append a forward slash */
192 strncat(config_file, "/", sizeof(config_file) - 2);
193 config_file[sizeof(config_file) - 1] = '\x0';
194
195 /* append the config file to the path */
196 strncat(config_file, buffer, sizeof(config_file) - strlen(config_file) - 1);
197 config_file[sizeof(config_file) - 1] = '\x0';
198 }
199
200 /* read the config file */
201 result = read_config_file(config_file);
202 /* exit if there are errors... */
203 if (result == ERROR) {
204 logit(LOG_ERR, "Config file '%s' contained errors, aborting...", config_file);
205 return STATE_CRITICAL;
206 }
207
208 if (!nasty_metachars)
209 nasty_metachars = strdup(NASTY_METACHARS);
210
211 /* initialize macros */
212 for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++)
213 macro_argv[x] = NULL;
214
215 init_ssl();
216
217 /* if we're running under inetd... */
218 if (use_inetd == TRUE)
219 run_inetd();
220
221 else if (use_src == TRUE || no_forking == TRUE)
222 run_src();
223
224 else
225 run_daemon();
226
227 #ifdef HAVE_SSL
228 if (use_ssl == TRUE)
229 SSL_CTX_free(ctx);
230 #endif
231
232 /* We are now running in daemon mode, or the connection handed over by inetd has
233 been completed, so the parent process exits */
234 return STATE_OK;
235 }
236
init(void)237 int init(void)
238 {
239 char *env_string = NULL;
240 int result = OK;
241
242 /* set some environment variables */
243 asprintf(&env_string, "NRPE_MULTILINESUPPORT=1");
244 putenv(env_string);
245 asprintf(&env_string, "NRPE_PROGRAMVERSION=%s", PROGRAM_VERSION);
246 putenv(env_string);
247
248 /* open a connection to the syslog facility */
249 /* facility name may be overridden later */
250 get_log_facility(NRPE_LOG_FACILITY);
251 openlog("nrpe", LOG_PID, log_facility);
252
253 /* generate the CRC 32 table */
254 generate_crc32_table();
255
256 return result;
257 }
258
init_ssl(void)259 void init_ssl(void)
260 {
261 #ifdef HAVE_SSL
262 DH *dh;
263 char seedfile[FILENAME_MAX];
264 char errstr[120] = { "" };
265 int i, c, x, vrfy;
266 unsigned long ssl_opts = SSL_OP_ALL | SSL_OP_SINGLE_DH_USE;
267
268 if (use_ssl == FALSE) {
269 if (debug == TRUE)
270 logit(LOG_INFO, "INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
271 return;
272 }
273
274 #ifndef USE_SSL_DH
275 ssl_opts = SSL_OP_ALL;
276 sslprm.allowDH = 0;
277 #endif
278
279 if (sslprm.log_opts & SSL_LogStartup)
280 log_ssl_startup();
281
282 /* initialize SSL */
283 SSL_load_error_strings();
284 SSL_library_init();
285 ENGINE_load_builtin_engines();
286 RAND_set_rand_engine(NULL);
287 ENGINE_register_all_complete();
288
289 meth = SSLv23_server_method();
290
291 /* use week random seed if necessary */
292 if (allow_weak_random_seed && (RAND_status() == 0)) {
293 if (RAND_file_name(seedfile, sizeof(seedfile) - 1))
294 if (RAND_load_file(seedfile, -1))
295 RAND_write_file(seedfile);
296
297 if (RAND_status() == 0) {
298 logit(LOG_ERR,
299 "Warning: SSL/TLS uses a weak random seed which is highly discouraged");
300 srand(time(NULL));
301 for (i = 0; i < 500 && RAND_status() == 0; i++) {
302 for (c = 0; c < sizeof(seedfile); c += sizeof(int)) {
303 *((int *)(seedfile + c)) = rand();
304 }
305 RAND_seed(seedfile, sizeof(seedfile));
306 }
307 }
308 }
309
310 #if OPENSSL_VERSION_NUMBER >= 0x10100000
311
312 meth = TLS_method();
313
314 #else /* OPENSSL_VERSION_NUMBER >= 0x10100000 */
315
316 # ifndef OPENSSL_NO_SSL2
317 if (sslprm.ssl_proto_ver == SSLv2)
318 meth = SSLv2_server_method();
319 # endif
320 # ifndef OPENSSL_NO_SSL3
321 if (sslprm.ssl_proto_ver == SSLv3)
322 meth = SSLv3_server_method();
323 # endif
324 if (sslprm.ssl_proto_ver == TLSv1)
325 meth = TLSv1_server_method();
326 # ifdef SSL_TXT_TLSV1_1
327 if (sslprm.ssl_proto_ver == TLSv1_1)
328 meth = TLSv1_1_server_method();
329 # ifdef SSL_TXT_TLSV1_2
330 if (sslprm.ssl_proto_ver == TLSv1_2)
331 meth = TLSv1_2_server_method();
332 # endif /* ifdef SSL_TXT_TLSV1_2 */
333 # endif /* SSL_TXT_TLSV1_1 */
334
335 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000 */
336
337 ctx = SSL_CTX_new(meth);
338 if (ctx == NULL) {
339 while ((x = ERR_get_error()) != 0) {
340 ERR_error_string(x, errstr);
341 logit(LOG_ERR, "Error: could not create SSL context : %s", errstr);
342 }
343 SSL_CTX_free(ctx);
344 exit(STATE_CRITICAL);
345 }
346
347 #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
348
349 SSL_CTX_set_max_proto_version(ctx, 0);
350
351 switch(sslprm.ssl_proto_ver) {
352
353 case TLSv1_2:
354 SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
355 case TLSv1_2_plus:
356 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
357 break;
358
359 case TLSv1_1:
360 SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
361 case TLSv1_1_plus:
362 SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
363 break;
364
365 case TLSv1:
366 SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
367 case TLSv1_plus:
368 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
369 break;
370
371 case SSLv3:
372 SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
373 case SSLv3_plus:
374 SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
375 break;
376 }
377
378 #else /* OPENSSL_VERSION_NUMBER >= 0x10100000 */
379
380 switch(sslprm.ssl_proto_ver) {
381 case SSLv2:
382 case SSLv2_plus:
383 break;
384 case TLSv1_2:
385 case TLSv1_2_plus:
386 #ifdef SSL_OP_NO_TLSv1_1
387 ssl_opts |= SSL_OP_NO_TLSv1_1;
388 #endif
389 case TLSv1_1:
390 case TLSv1_1_plus:
391 ssl_opts |= SSL_OP_NO_TLSv1;
392 case TLSv1:
393 case TLSv1_plus:
394 ssl_opts |= SSL_OP_NO_SSLv3;
395 case SSLv3:
396 case SSLv3_plus:
397 ssl_opts |= SSL_OP_NO_SSLv2;
398 break;
399 }
400
401 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000 */
402
403 SSL_CTX_set_options(ctx, ssl_opts);
404
405 if (sslprm.cert_file != NULL) {
406 if (!SSL_CTX_use_certificate_file(ctx, sslprm.cert_file, SSL_FILETYPE_PEM)) {
407 SSL_CTX_free(ctx);
408 while ((x = ERR_get_error()) != 0) {
409 ERR_error_string(x, errstr);
410 logit(LOG_ERR, "Error: could not use certificate file %s : %s",
411 sslprm.cert_file, errstr);
412 }
413 exit(STATE_CRITICAL);
414 }
415 if (!SSL_CTX_use_PrivateKey_file(ctx, sslprm.privatekey_file, SSL_FILETYPE_PEM)) {
416 while ((x = ERR_get_error()) != 0) {
417 ERR_error_string(x, errstr);
418 logit(LOG_ERR, "Error: could not use private key file '%s' : %s",
419 sslprm.privatekey_file, errstr);
420 }
421 SSL_CTX_free(ctx);
422 exit(STATE_CRITICAL);
423 }
424 }
425
426 if (sslprm.client_certs != 0) {
427 vrfy = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
428 if ((sslprm.client_certs & Require_Cert) != 0)
429 vrfy |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
430 SSL_CTX_set_verify(ctx, vrfy, verify_callback);
431 if (!SSL_CTX_load_verify_locations(ctx, sslprm.cacert_file, NULL)) {
432 while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
433 logit(LOG_ERR, "Error: could not use CA certificate file '%s': %s\n",
434 sslprm.cacert_file, ERR_reason_error_string(x));
435 }
436 SSL_CTX_free(ctx);
437 logit(LOG_ERR, "Error: could not use CA certificate '%s'", sslprm.cacert_file);
438 exit(STATE_CRITICAL);
439 }
440 }
441
442 if (!sslprm.allowDH) {
443 if (strlen(sslprm.cipher_list) < sizeof(sslprm.cipher_list) - 6)
444 strcat(sslprm.cipher_list, ":!ADH");
445 } else {
446 /* use anonymous DH ciphers */
447 if (sslprm.allowDH == 2) {
448 #if OPENSSL_VERSION_NUMBER >= 0x10100000
449 strncpy(sslprm.cipher_list, "ADH@SECLEVEL=0", MAX_FILENAME_LENGTH - 1);
450 #else
451 strncpy(sslprm.cipher_list, "ADH", MAX_FILENAME_LENGTH - 1);
452 #endif
453 }
454
455 #ifdef USE_SSL_DH
456 dh = get_dh2048();
457 SSL_CTX_set_tmp_dh(ctx, dh);
458 DH_free(dh);
459 #endif
460 }
461
462 if (SSL_CTX_set_cipher_list(ctx, sslprm.cipher_list) == 0) {
463 SSL_CTX_free(ctx);
464 logit(LOG_ERR, "Error: Could not set SSL/TLS cipher list");
465 exit(STATE_CRITICAL);
466 }
467
468 if (debug == TRUE)
469 logit(LOG_INFO, "INFO: SSL/TLS initialized. All network traffic will be encrypted.");
470 #endif
471 }
472
log_ssl_startup(void)473 void log_ssl_startup(void)
474 {
475 #ifdef HAVE_SSL
476 char *vers;
477
478 logit(LOG_INFO, "SSL Certificate File: %s", sslprm.cert_file ? sslprm.cert_file : "None");
479 logit(LOG_INFO, "SSL Private Key File: %s",
480 sslprm.privatekey_file ? sslprm.privatekey_file : "None");
481 logit(LOG_INFO, "SSL CA Certificate File: %s",
482 sslprm.cacert_file ? sslprm.cacert_file : "None");
483 logit(LOG_INFO, "SSL Cipher List: %s", sslprm.cipher_list);
484 logit(LOG_INFO, "SSL Allow ADH: %d", sslprm.allowDH == 0);
485 logit(LOG_INFO, "SSL Client Certs: %s",
486 sslprm.client_certs == 0 ? "Don't Ask" : (sslprm.client_certs ==
487 1 ? "Accept" : "Require"));
488 logit(LOG_INFO, "SSL Log Options: 0x%02x", sslprm.log_opts);
489 switch (sslprm.ssl_proto_ver) {
490 case SSLv2:
491 vers = "SSLv2";
492 break;
493 case SSLv2_plus:
494 vers = "SSLv2 And Above";
495 break;
496 case SSLv3:
497 vers = "SSLv3";
498 break;
499 case SSLv3_plus:
500 vers = "SSLv3 And Above";
501 break;
502 case TLSv1:
503 vers = "TLSv1";
504 break;
505 case TLSv1_plus:
506 vers = "TLSv1 And Above";
507 break;
508 case TLSv1_1:
509 vers = "TLSv1_1";
510 break;
511 case TLSv1_1_plus:
512 vers = "TLSv1_1 And Above";
513 break;
514 case TLSv1_2:
515 vers = "TLSv1_2";
516 break;
517 case TLSv1_2_plus:
518 vers = "TLSv1_2 And Above";
519 break;
520 default:
521 vers = "INVALID VALUE!";
522 break;
523 }
524 logit(LOG_INFO, "SSL Version: %s", vers);
525 #endif
526 }
527
usage(int result)528 void usage(int result)
529 {
530 if (result != OK) {
531 printf("\n");
532 printf("Incorrect command line arguments supplied\n");
533 printf("\n");
534 }
535 printf("NRPE - Nagios Remote Plugin Executor\n");
536 printf("Version: %s\n", PROGRAM_VERSION);
537 printf("\n");
538 if (result != OK || show_help == TRUE) {
539 printf("Copyright (c) 2009-2017 Nagios Enterprises\n");
540 printf(" 1999-2008 Ethan Galstad (nagios@nagios.org)\n");
541 printf("\n");
542 printf("Last Modified: %s\n", MODIFICATION_DATE);
543 printf("\n");
544 printf("License: GPL v2 with exemptions (-l for more info)\n");
545 printf("\n");
546 #ifdef HAVE_SSL
547 printf("SSL/TLS Available, OpenSSL 0.9.6 or higher required\n");
548 printf("\n");
549 #endif
550 #ifdef HAVE_LIBWRAP
551 printf("TCP Wrappers Available\n");
552 printf("\n");
553 #endif
554 #ifdef ENABLE_COMMAND_ARGUMENTS
555 printf("***************************************************************\n");
556 printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
557 printf("** Read the NRPE SECURITY file for more information **\n");
558 printf("***************************************************************\n");
559 printf("\n");
560 #endif
561 #ifndef HAVE_LIBWRAP
562 printf("***************************************************************\n");
563 printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE! **\n");
564 printf("** Read the NRPE SECURITY file for more information **\n");
565 printf("***************************************************************\n");
566 printf("\n");
567 #endif
568 printf("Usage: nrpe [-V] [-n] -c <config_file> [-4|-6] <mode>\n");
569 printf("\n");
570 printf("Options:\n");
571 printf(" -V, --version Print version info and quit\n");
572 printf(" -n, --no-ssl Do not use SSL\n");
573 printf(" -c, --config=FILE Name of config file to use\n");
574 printf(" -4, --ipv4 Use ipv4 only\n");
575 printf(" -6, --ipv6 Use ipv6 only\n");
576 printf(" <mode> (One of the following operating modes)\n");
577 printf(" -i, --inetd Run as a service under inetd or xinetd\n");
578 printf(" -d, --daemon Run as a standalone daemon\n");
579 printf(" -s, --src Run as a subsystem under AIX\n");
580 printf(" -f, --no-forking Don't fork() (for systemd, launchd, etc.)\n");
581 printf("\n");
582 printf("Notes:\n");
583 printf("This program is designed to process requests from the check_nrpe\n");
584 printf("plugin on the host(s) running Nagios. It can run as a service\n");
585 printf("under inetd or xinetd (read the docs for info on this), or as a\n");
586 printf("standalone daemon. Once a request is received from an authorized\n");
587 printf("host, NRPE will execute the command/plugin (as defined in the\n");
588 printf("config file) and return the plugin output and return code to the\n");
589 printf("check_nrpe plugin.\n");
590 printf("\n");
591 }
592
593 if (show_license == TRUE)
594 display_license();
595
596 exit(STATE_UNKNOWN);
597 }
598
run_inetd(void)599 void run_inetd(void)
600 {
601 check_privileges(); /* make sure we're not root */
602 close(2); /* redirect STDERR to /dev/null */
603 open("/dev/null", O_WRONLY);
604 handle_connection(0); /* handle the connection */
605 }
606
run_src(void)607 void run_src(void)
608 {
609 /* if we're running under SRC we don't fork but does drop-privileges */
610
611 set_stdio_sigs();
612
613 do {
614 /* reset flags */
615 sigrestart = FALSE;
616 sigshutdown = FALSE;
617
618 wait_for_connections(); /* wait for connections */
619 cleanup();
620 } while (sigrestart == TRUE && sigshutdown == FALSE);
621 }
622
623 /* daemonize and start listening for requests... */
run_daemon(void)624 void run_daemon(void)
625 {
626 pid_t pid;
627
628 pid = fork();
629
630 if (pid != 0) {
631 if (pid == -1) {
632 logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
633 exit(STATE_CRITICAL);
634 }
635
636 return;
637 }
638
639 setsid(); /* we're a daemon - set up a new process group */
640 set_stdio_sigs();
641
642 do {
643 /* reset flags */
644 sigrestart = FALSE;
645 sigshutdown = FALSE;
646
647 wait_for_connections(); /* wait for connections */
648 cleanup();
649 } while (sigrestart == TRUE && sigshutdown == FALSE);
650 }
651
set_stdio_sigs(void)652 void set_stdio_sigs(void)
653 {
654 #ifdef HAVE_SIGACTION
655 struct sigaction sig_action;
656 #endif
657
658 if (chdir("/") == -1) {
659 printf("ERROR: chdir(): %s, bailing out...\n", strerror(errno));
660 exit(STATE_CRITICAL);
661 }
662
663 close(0); /* close standard file descriptors */
664 close(1);
665 close(2);
666 open("/dev/null", O_RDONLY); /* redirect standard descriptors to /dev/null */
667 open("/dev/null", O_WRONLY);
668 open("/dev/null", O_WRONLY);
669
670 /* handle signals */
671 #ifdef HAVE_SIGACTION
672 sig_action.sa_sigaction = NULL;
673 sig_action.sa_handler = sighandler;
674 sigfillset(&sig_action.sa_mask);
675 sig_action.sa_flags = SA_NODEFER | SA_RESTART;
676 sigaction(SIGQUIT, &sig_action, NULL);
677 sigaction(SIGTERM, &sig_action, NULL);
678 sigaction(SIGHUP, &sig_action, NULL);
679 #else /* HAVE_SIGACTION */
680 signal(SIGQUIT, sighandler);
681 signal(SIGTERM, sighandler);
682 signal(SIGHUP, sighandler);
683 #endif /* HAVE_SIGACTION */
684
685 logit(LOG_NOTICE, "Starting up daemon"); /* log info */
686 if (write_pid_file() == ERROR) /* write pid file */
687 exit(STATE_CRITICAL);
688
689 clean_environ(keep_env_vars, nrpe_user);
690
691 /* drop and then check privileges */
692 drop_privileges(nrpe_user, nrpe_group, 0);
693 check_privileges();
694 }
695
cleanup(void)696 void cleanup(void)
697 {
698 int result;
699
700 free_memory(); /* free all memory we allocated */
701
702 if (sigrestart == TRUE && sigshutdown == FALSE) {
703 close_log_file();
704 result = read_config_file(config_file); /* read the config file */
705
706 if (result == ERROR) { /* exit if there are errors... */
707 logit(LOG_ERR, "Config file '%s' contained errors, bailing out...", config_file);
708 exit(STATE_CRITICAL);
709 }
710 return;
711 }
712
713 remove_pid_file(); /* remove pid file */
714 logit(LOG_NOTICE, "Daemon shutdown\n");
715
716 close_log_file(); /* close the log file */
717 }
718
719 #ifdef HAVE_SSL
verify_callback(int preverify_ok,X509_STORE_CTX * ctx)720 int verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
721 {
722 char name[256], issuer[256];
723 X509 *err_cert;
724 int err;
725 SSL *ssl;
726
727 if (preverify_ok || ((sslprm.log_opts & SSL_LogCertDetails) == 0))
728 return preverify_ok;
729
730 err_cert = X509_STORE_CTX_get_current_cert(ctx);
731 err = X509_STORE_CTX_get_error(ctx);
732
733 /* Get the pointer to the SSL of the current connection */
734 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
735
736 X509_NAME_oneline(X509_get_subject_name(err_cert), name, 256);
737 X509_NAME_oneline(X509_get_issuer_name(err_cert), issuer, 256);
738
739 if (!preverify_ok && (sslprm.log_opts & SSL_LogCertDetails)) {
740 logit(LOG_ERR, "SSL Client has an invalid certificate: %s (issuer=%s) err=%d:%s",
741 name, issuer, err, X509_verify_cert_error_string(err));
742 }
743
744 return preverify_ok;
745 }
746 #endif
747
748 /* read in the configuration file */
read_config_file(char * filename)749 int read_config_file(char *filename)
750 {
751 struct stat st;
752 FILE *fp;
753 char config_file[MAX_FILENAME_LENGTH];
754 char input_buffer[MAX_INPUT_BUFFER];
755 char *input_line;
756 char *temp_buffer;
757 char *varname;
758 char *varvalue;
759 int line = 0;
760 int len = 0;
761 int x = 0;
762
763 fp = fopen(filename, "r"); /* open the config file for reading */
764
765 /* exit if we couldn't open the config file */
766 if (fp == NULL) {
767 logit(LOG_ERR, "Unable to open config file '%s' for reading\n", filename);
768 return ERROR;
769 }
770
771 while (fgets(input_buffer, MAX_INPUT_BUFFER - 1, fp)) {
772 line++;
773 input_line = input_buffer;
774
775 /* skip leading whitespace */
776 while (isspace(*input_line))
777 ++input_line;
778
779 /* trim trailing whitespace */
780 len = strlen(input_line);
781 for (x = len - 1; x >= 0; x--) {
782 if (isspace(input_line[x]))
783 input_line[x] = '\x0';
784 else
785 break;
786 }
787
788 /* skip comments and blank lines */
789 if (input_line[0] == '#' || input_line[0] == '\x0' || input_line[0] == '\n')
790 continue;
791
792 /* get the variable name */
793 varname = strtok(input_line, "=");
794 if (varname == NULL) {
795 logit(LOG_ERR, "No variable name specified in config file '%s' - Line %d\n",
796 filename, line);
797 return ERROR;
798 }
799
800 /* get the variable value */
801 varvalue = strtok(NULL, "\n");
802 if (varvalue == NULL) {
803 logit(LOG_ERR, "No variable value specified in config file '%s' - Line %d\n",
804 filename, line);
805 return ERROR;
806
807 } else if (!strcmp(varname, "include_dir")) {
808 /* allow users to specify directories to recurse into for config files */
809
810 strncpy(config_file, varvalue, sizeof(config_file) - 1);
811 config_file[sizeof(config_file) - 1] = '\x0';
812
813 /* strip trailing / if necessary */
814 if (config_file[strlen(config_file) - 1] == '/')
815 config_file[strlen(config_file) - 1] = '\x0';
816
817 /* process the config directory... */
818 if (read_config_dir(config_file) == ERROR)
819 logit(LOG_ERR, "Continuing with errors...");
820
821 } else if (!strcmp(varname, "include") || !strcmp(varname, "include_file")) {
822 /* allow users to specify individual config files to include */
823
824 /* process the config file... */
825 if (read_config_file(varvalue) == ERROR)
826 logit(LOG_ERR, "Continuing with errors...");
827
828 } else if (!strcmp(varname, "max_commands")) {
829
830 max_commands = atoi(varvalue);
831 if (max_commands < 0) {
832 logit(LOG_WARNING, "max_commands set too low, setting to 0\n");
833 max_commands = 0;
834 }
835
836 } else if (!strcmp(varname, "server_port")) {
837 server_port = atoi(varvalue);
838 if (server_port < 1024) {
839 logit(LOG_ERR,
840 "Invalid port number specified in config file '%s' - Line %d\n",
841 filename, line);
842 return ERROR;
843 }
844
845 } else if (!strcmp(varname, "command_prefix"))
846 command_prefix = strdup(varvalue);
847
848 else if (!strcmp(varname, "server_address")) {
849 strncpy(server_address, varvalue, sizeof(server_address) - 1);
850 server_address[sizeof(server_address) - 1] = '\0';
851
852 } else if (!strcmp(varname, "allowed_hosts")) {
853 allowed_hosts = strdup(varvalue);
854 parse_allowed_hosts(allowed_hosts);
855 if (debug == TRUE)
856 show_acl_lists();
857
858 } else if (strstr(input_line, "command[")) {
859 temp_buffer = strtok(varname, "[");
860 temp_buffer = strtok(NULL, "]");
861 if (temp_buffer == NULL) {
862 logit(LOG_ERR, "Invalid command specified in config file '%s' - Line %d\n",
863 filename, line);
864 return ERROR;
865 }
866 add_command(temp_buffer, varvalue);
867
868 } else if (strstr(input_buffer, "debug")) {
869 debug = atoi(varvalue);
870 if (debug > 0)
871 debug = TRUE;
872 else
873 debug = FALSE;
874
875 } else if (!strcmp(varname, "nrpe_user"))
876 nrpe_user = strdup(varvalue);
877
878 else if (!strcmp(varname, "nrpe_group"))
879 nrpe_group = strdup(varvalue);
880
881 else if (!strcmp(varname, "dont_blame_nrpe"))
882 allow_arguments = (atoi(varvalue) == 1) ? TRUE : FALSE;
883
884 else if (!strcmp(varname, "allow_bash_command_substitution"))
885 allow_bash_cmd_subst = (atoi(varvalue) == 1) ? TRUE : FALSE;
886
887 else if (!strcmp(varname, "command_timeout")) {
888 command_timeout = atoi(varvalue);
889 if (command_timeout < 1) {
890 logit(LOG_ERR,
891 "Invalid command_timeout specified in config file '%s' - Line %d\n",
892 filename, line);
893 return ERROR;
894 }
895 } else if (!strcmp(varname, "connection_timeout")) {
896 connection_timeout = atoi(varvalue);
897 if (connection_timeout < 1) {
898 logit(LOG_ERR,
899 "Invalid connection_timeout specified in config file '%s' - Line %d\n",
900 filename, line);
901 return ERROR;
902 }
903
904 } else if (!strcmp(varname, "ssl_shutdown_timeout")) {
905 ssl_shutdown_timeout = atoi(varvalue);
906 if (ssl_shutdown_timeout < 1) {
907 logit(LOG_ERR,
908 "Invalid ssl_shutdown_timeout specified in config file '%s' - Line %d\n",
909 filename, line);
910 return ERROR;
911 }
912
913 } else if (!strcmp(varname, "allow_weak_random_seed"))
914 allow_weak_random_seed = (atoi(varvalue) == 1) ? TRUE : FALSE;
915
916 else if (!strcmp(varname, "pid_file"))
917 pid_file = strdup(varvalue);
918
919 else if (!strcmp(varname, "listen_queue_size")) {
920 listen_queue_size = atoi(varvalue);
921 if (listen_queue_size == 0) {
922 logit(LOG_ERR,
923 "Invalid listen queue size specified in config file '%s' - Line %d\n",
924 filename, line);
925 return ERROR;
926 }
927
928 } else if (!strcmp(varname, "ssl_version")) {
929 if (!strcmp(varvalue, "TLSv1.2"))
930 sslprm.ssl_proto_ver = TLSv1_2;
931 else if (!strcmp(varvalue, "TLSv1.2+"))
932 sslprm.ssl_proto_ver = TLSv1_2_plus;
933 else if (!strcmp(varvalue, "TLSv1.1"))
934 sslprm.ssl_proto_ver = TLSv1_1;
935 else if (!strcmp(varvalue, "TLSv1.1+"))
936 sslprm.ssl_proto_ver = TLSv1_1_plus;
937 else if (!strcmp(varvalue, "TLSv1"))
938 sslprm.ssl_proto_ver = TLSv1;
939 else if (!strcmp(varvalue, "TLSv1+"))
940 sslprm.ssl_proto_ver = TLSv1_plus;
941 else if (!strcmp(varvalue, "SSLv3"))
942 sslprm.ssl_proto_ver = SSLv3;
943 else if (!strcmp(varvalue, "SSLv3+"))
944 sslprm.ssl_proto_ver = SSLv3_plus;
945 #if OPENSSL_VERSION_NUMBER < 0x10100000
946 else if (!strcmp(varvalue, "SSLv2"))
947 sslprm.ssl_proto_ver = SSLv2;
948 else if (!strcmp(varvalue, "SSLv2+"))
949 sslprm.ssl_proto_ver = SSLv2_plus;
950 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */
951 else {
952 logit(LOG_ERR, "Invalid ssl version specified in config file '%s' - Line %d",
953 filename, line);
954 return ERROR;
955 }
956
957 } else if (!strcmp(varname, "ssl_use_adh")) {
958 sslprm.allowDH = atoi(varvalue);
959 if (sslprm.allowDH < 0 || sslprm.allowDH > 2) {
960 logit(LOG_ERR,
961 "Invalid use adh value specified in config file '%s' - Line %d",
962 filename, line);
963 return ERROR;
964 }
965
966 } else if (!strcmp(varname, "ssl_logging"))
967 sslprm.log_opts = strtoul(varvalue, NULL, 0);
968
969 else if (!strcmp(varname, "ssl_cipher_list")) {
970 strncpy(sslprm.cipher_list, varvalue, sizeof(sslprm.cipher_list) - 1);
971 sslprm.cipher_list[sizeof(sslprm.cipher_list) - 1] = '\0';
972
973 } else if (!strcmp(varname, "ssl_cert_file"))
974 sslprm.cert_file = strdup(varvalue);
975
976 else if (!strcmp(varname, "ssl_cacert_file"))
977 sslprm.cacert_file = strdup(varvalue);
978
979 else if (!strcmp(varname, "ssl_privatekey_file"))
980 sslprm.privatekey_file = strdup(varvalue);
981
982 else if (!strcmp(varname, "ssl_client_certs")) {
983 sslprm.client_certs = atoi(varvalue);
984 if ((int)sslprm.client_certs < 0 || sslprm.client_certs > Require_Cert) {
985 logit(LOG_ERR,
986 "Invalid client certs value specified in config file '%s' - Line %d",
987 filename, line);
988 return ERROR;
989 }
990 /* if requiring or logging client certs, make sure "Ask" is turned on */
991 if (sslprm.client_certs & Require_Cert)
992 sslprm.client_certs |= Ask_For_Cert;
993
994 } else if (!strcmp(varname, "log_facility")) {
995 if ((get_log_facility(varvalue)) == OK) {
996 /* re-open log using new facility */
997 closelog();
998 openlog("nrpe", LOG_PID, log_facility);
999 } else
1000 logit(LOG_WARNING,
1001 "Invalid log_facility specified in config file '%s' - Line %d\n",
1002 filename, line);
1003
1004 } else if (!strcmp(varname, "keep_env_vars"))
1005 keep_env_vars = strdup(varvalue);
1006
1007 else if (!strcmp(varname, "nasty_metachars"))
1008 nasty_metachars = strdup(varvalue);
1009
1010 else if (!strcmp(varname, "log_file")) {
1011 log_file = strdup(varvalue);
1012 open_log_file();
1013
1014 } else {
1015 logit(LOG_WARNING, "Unknown option specified in config file '%s' - Line %d\n",
1016 filename, line);
1017 continue;
1018 }
1019 }
1020
1021 fclose(fp); /* close the config file */
1022 return OK;
1023 }
1024
1025 /* process all config files in a specific config directory (with directory recursion) */
read_config_dir(char * dirname)1026 int read_config_dir(char *dirname)
1027 {
1028 struct dirent *dirfile;
1029 #ifdef HAVE_SCANDIR
1030 struct dirent **dirfiles;
1031 int x, i, n;
1032 #else
1033 DIR *dirp;
1034 int x;
1035 #endif
1036 struct stat buf;
1037 char config_file[MAX_FILENAME_LENGTH];
1038 int result = OK;
1039
1040 #ifdef HAVE_SCANDIR
1041 /* read and sort the directory contents */
1042 n = scandir(dirname, &dirfiles, 0, alphasort);
1043 if (n < 0) {
1044 logit(LOG_ERR, "Could not open config directory '%s' for reading.\n", dirname);
1045 return ERROR;
1046 }
1047
1048 for (i = 0; i < n; i++) {
1049 dirfile = dirfiles[i];
1050 #else
1051 /* open the directory for reading */
1052 dirp = opendir(dirname);
1053 if (dirp == NULL) {
1054 logit(LOG_ERR, "Could not open config directory '%s' for reading.\n", dirname);
1055 return ERROR;
1056 }
1057
1058 while ((dirfile = readdir(dirp)) != NULL) {
1059 #endif
1060
1061 /* process all files in the directory... */
1062
1063 /* create the full path to the config file or subdirectory */
1064 snprintf(config_file, sizeof(config_file) - 1, "%s/%s", dirname, dirfile->d_name);
1065 config_file[sizeof(config_file) - 1] = '\x0';
1066 stat(config_file, &buf);
1067
1068 /* process this if it's a config file... */
1069 x = strlen(dirfile->d_name);
1070 if (x > 4 && !strcmp(dirfile->d_name + (x - 4), ".cfg")) {
1071
1072 /* only process normal files */
1073 if (!S_ISREG(buf.st_mode))
1074 continue;
1075
1076 /* process the config file */
1077 result = read_config_file(config_file);
1078
1079 /* break out if we encountered an error */
1080 if (result == ERROR)
1081 break;
1082 }
1083
1084 /* recurse into subdirectories... */
1085 if (S_ISDIR(buf.st_mode)) {
1086
1087 /* ignore current, parent and hidden directory entries */
1088 if (dirfile->d_name[0] == '.')
1089 continue;
1090
1091 /* process the config directory */
1092 result = read_config_dir(config_file);
1093
1094 /* break out if we encountered an error */
1095 if (result == ERROR)
1096 break;
1097
1098 }
1099 }
1100
1101 #ifdef HAVE_SCANDIR
1102 for (i = 0; i < n; i++)
1103 free(dirfiles[i]);
1104 free(dirfiles);
1105 #else
1106 closedir(dirp);
1107 #endif
1108
1109 return result;
1110 }
1111
1112 /* determines facility to use with syslog */
1113 int get_log_facility(char *varvalue)
1114 {
1115 if (!strcmp(varvalue, "kern"))
1116 log_facility = LOG_KERN;
1117 else if (!strcmp(varvalue, "user"))
1118 log_facility = LOG_USER;
1119 else if (!strcmp(varvalue, "mail"))
1120 log_facility = LOG_MAIL;
1121 else if (!strcmp(varvalue, "daemon"))
1122 log_facility = LOG_DAEMON;
1123 else if (!strcmp(varvalue, "auth"))
1124 log_facility = LOG_AUTH;
1125 else if (!strcmp(varvalue, "syslog"))
1126 log_facility = LOG_SYSLOG;
1127 else if (!strcmp(varvalue, "lrp"))
1128 log_facility = LOG_LPR;
1129 else if (!strcmp(varvalue, "news"))
1130 log_facility = LOG_NEWS;
1131 else if (!strcmp(varvalue, "uucp"))
1132 log_facility = LOG_UUCP;
1133 else if (!strcmp(varvalue, "cron"))
1134 log_facility = LOG_CRON;
1135 else if (!strcmp(varvalue, "authpriv"))
1136 log_facility = LOG_AUTHPRIV;
1137 else if (!strcmp(varvalue, "ftp"))
1138 log_facility = LOG_FTP;
1139 else if (!strcmp(varvalue, "local0"))
1140 log_facility = LOG_LOCAL0;
1141 else if (!strcmp(varvalue, "local1"))
1142 log_facility = LOG_LOCAL1;
1143 else if (!strcmp(varvalue, "local2"))
1144 log_facility = LOG_LOCAL2;
1145 else if (!strcmp(varvalue, "local3"))
1146 log_facility = LOG_LOCAL3;
1147 else if (!strcmp(varvalue, "local4"))
1148 log_facility = LOG_LOCAL4;
1149 else if (!strcmp(varvalue, "local5"))
1150 log_facility = LOG_LOCAL5;
1151 else if (!strcmp(varvalue, "local6"))
1152 log_facility = LOG_LOCAL6;
1153 else if (!strcmp(varvalue, "local7"))
1154 log_facility = LOG_LOCAL7;
1155 else {
1156 log_facility = LOG_DAEMON;
1157 return ERROR;
1158 }
1159
1160 return OK;
1161 }
1162
1163 /* adds a new command definition from the config file to the list in memory */
1164 int add_command(char *command_name, char *command_line)
1165 {
1166 command *new_command;
1167
1168 if (command_name == NULL || command_line == NULL)
1169 return ERROR;
1170
1171 /* allocate memory for the new command */
1172 new_command = (command *) malloc(sizeof(command));
1173 if (new_command == NULL)
1174 return ERROR;
1175
1176 new_command->command_name = strdup(command_name);
1177 if (new_command->command_name == NULL) {
1178 free(new_command);
1179 return ERROR;
1180 }
1181 new_command->command_line = strdup(command_line);
1182 if (new_command->command_line == NULL) {
1183 free(new_command->command_name);
1184 free(new_command);
1185 return ERROR;
1186 }
1187
1188 /* add new command to head of list in memory */
1189 new_command->next = command_list;
1190 command_list = new_command;
1191
1192 if (debug == TRUE)
1193 logit(LOG_DEBUG, "Added command[%s]=%s\n", command_name, command_line);
1194
1195 return OK;
1196 }
1197
1198 /* given a command name, find the structure in memory */
1199 command *find_command(char *command_name)
1200 {
1201 command *temp_command;
1202
1203 for (temp_command = command_list; temp_command != NULL; temp_command = temp_command->next)
1204 if (!strcmp(command_name, temp_command->command_name))
1205 return temp_command;
1206
1207 return NULL;
1208 }
1209
1210 /* Start listen on a particular port */
1211 void create_listener(struct addrinfo *ai)
1212 {
1213 int ret;
1214 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1215 int listen_sock;
1216 int flag = 1;
1217
1218 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
1219 return;
1220
1221 if (num_listen_socks >= MAX_LISTEN_SOCKS) {
1222 logit(LOG_ERR, "Too many listen sockets. Enlarge MAX_LISTEN_SOCKS");
1223 exit(1);
1224 }
1225
1226 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1227 strport, sizeof(strport), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
1228 logit(LOG_ERR, "getnameinfo failed: %.100s", gai_strerror(ret));
1229 return;
1230 }
1231
1232 /* Create socket for listening. */
1233 listen_sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
1234 if (listen_sock < 0) {
1235 /* kernel may not support ipv6 */
1236 logit(LOG_ERR, "socket: %.100s", strerror(errno));
1237 return;
1238 }
1239
1240 /* socket should be non-blocking */
1241 fcntl(listen_sock, F_SETFL, O_NONBLOCK);
1242
1243 /* set the reuse address flag so we don't get errors when restarting */
1244 if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0) {
1245 logit(LOG_ERR, "setsockopt SO_REUSEADDR: %s", strerror(errno));
1246 return;
1247 }
1248 #ifdef IPV6_V6ONLY
1249 /* Only communicate in IPv6 over AF_INET6 sockets. */
1250 if (ai->ai_family == AF_INET6) {
1251 if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == -1) {
1252 fprintf(stderr, "setsockopt IPV6_V6ONLY: %s", strerror(errno));
1253 }
1254 }
1255 #endif
1256
1257 /* Bind the socket to the desired port. */
1258 if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
1259 logit(LOG_ERR, "Bind to port %s on %s failed: %.200s.",
1260 strport, ntop, strerror(errno));
1261 close(listen_sock);
1262 return;
1263 }
1264 listen_socks[num_listen_socks] = listen_sock;
1265 num_listen_socks++;
1266
1267 /* Start listening on the port. */
1268 if (listen(listen_sock, listen_queue_size) < 0) {
1269 logit(LOG_ERR, "listen on [%s]:%s: %.100s", ntop, strport, strerror(errno));
1270 exit(1);
1271 }
1272
1273 logit(LOG_INFO, "Server listening on %s port %s.", ntop, strport);
1274 }
1275
1276 /* Close all listening sockets */
1277 static void close_listen_socks(void)
1278 {
1279 int i;
1280
1281 for (i = 0; i <= num_listen_socks; i++) {
1282 close(listen_socks[i]);
1283 num_listen_socks--;
1284 }
1285 }
1286
1287 /* wait for incoming connection requests */
1288 void wait_for_connections(void)
1289 {
1290 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1291 struct sockaddr_storage from;
1292 #else
1293 struct sockaddr from;
1294 #endif
1295 socklen_t fromlen;
1296 fd_set *fdset = NULL;
1297 int maxfd = 0, new_sd = 0, i, rc, retval;
1298
1299 setup_wait_conn();
1300
1301 /* listen for connection requests - fork() if we get one */
1302 while (1) {
1303 /* bail out if necessary */
1304 if (sigrestart == TRUE || sigshutdown == TRUE)
1305 break;
1306
1307 for (i = 0; i < num_listen_socks; i++) {
1308 if (listen_socks[i] > maxfd)
1309 maxfd = listen_socks[i];
1310 }
1311
1312 if (fdset != NULL)
1313 free(fdset);
1314 fdset = (fd_set *) calloc(how_many(maxfd + 1, NFDBITS), sizeof(fd_mask));
1315
1316 for (i = 0; i < num_listen_socks; i++)
1317 FD_SET(listen_socks[i], fdset);
1318
1319 /* Wait in select until there is a connection. */
1320 retval = select(maxfd + 1, fdset, NULL, NULL, NULL);
1321
1322 /* bail out if necessary */
1323 if (sigrestart == TRUE || sigshutdown == TRUE)
1324 break;
1325
1326 /* error */
1327 if (retval < 0)
1328 continue;
1329
1330 for (i = 0; i < num_listen_socks; i++) {
1331 if (!FD_ISSET(listen_socks[i], fdset))
1332 continue;
1333 fromlen = (socklen_t)sizeof(from);
1334
1335 /* accept a new connection request */
1336 new_sd = accept(listen_socks[i], (struct sockaddr *)&from, &fromlen);
1337
1338 /* some kind of error occurred... */
1339 if (new_sd < 0) {
1340 /* bail out if necessary */
1341 if (sigrestart == TRUE || sigshutdown == TRUE)
1342 break;
1343 if (errno == EWOULDBLOCK || errno == EINTR) /* retry */
1344 continue;
1345 /* socket is nonblocking and we don't have a connection yet */
1346 if (errno == EAGAIN)
1347 continue;
1348 if (errno == ENOBUFS) /* fix for HP-UX 11.0 - just retry */
1349 continue;
1350
1351 break; /* else handle the error later */
1352 }
1353
1354
1355 rc = wait_conn_fork(new_sd);
1356 if (rc == TRUE)
1357 continue; /* Continue if this is the parent returning */
1358
1359 /* grandchild running here */
1360 conn_check_peer(new_sd);
1361
1362 /* handle the client connection */
1363 handle_connection(new_sd);
1364
1365 /* log info */
1366 if (debug == TRUE)
1367 logit(LOG_DEBUG, "Connection from %s closed.", remote_host);
1368
1369 /* close socket prior to exiting */
1370 close(new_sd);
1371
1372 exit(STATE_OK);
1373
1374 }
1375 }
1376
1377 /* close the sockets we're listening on */
1378 close_listen_socks();
1379 freeaddrinfo(listen_addrs);
1380 listen_addrs = NULL;
1381
1382 return;
1383 }
1384
1385 void setup_wait_conn(void)
1386 {
1387 struct addrinfo *ai;
1388 char addrstr[100];
1389 void *ptr;
1390
1391 add_listen_addr(&listen_addrs, address_family,
1392 (strcmp(server_address, "") == 0) ? NULL : server_address, server_port);
1393
1394 for (ai = listen_addrs; ai; ai = ai->ai_next) {
1395 if (debug == TRUE) {
1396 inet_ntop (ai->ai_family, ai->ai_addr->sa_data, addrstr, 100);
1397 ptr = &((struct sockaddr_in *) ai->ai_addr)->sin_addr;
1398 inet_ntop (ai->ai_family, ptr, addrstr, 100);
1399 logit(LOG_INFO, "SETUP_WAIT_CONN FOR: IPv4 address: %s (%s)\n", addrstr, ai->ai_canonname);
1400 }
1401 create_listener(ai);
1402 }
1403
1404 if (!num_listen_socks) {
1405 logit(LOG_ERR, "Cannot bind to any address.");
1406 exit(1);
1407 }
1408
1409 /* log warning about command arguments */
1410 #ifdef ENABLE_COMMAND_ARGUMENTS
1411 if (allow_arguments == TRUE)
1412 logit(LOG_NOTICE,
1413 "Warning: Daemon is configured to accept command arguments from clients!");
1414 # ifdef ENABLE_BASH_COMMAND_SUBSTITUTION
1415 if (TRUE == allow_bash_cmd_subst) {
1416 if (TRUE == allow_arguments)
1417 logit(LOG_NOTICE,
1418 "Warning: Daemon is configured to accept command arguments with bash command substitutions!");
1419 else
1420 logit(LOG_NOTICE,
1421 "Warning: Daemon is configured to accept command arguments with bash command substitutions, but is not configured to accept command arguments from clients. Enable command arguments if you wish to allow command arguments with bash command substitutions.");
1422 }
1423 # endif
1424 #endif
1425
1426 logit(LOG_INFO, "Listening for connections on port %d", server_port);
1427
1428 if (allowed_hosts)
1429 logit(LOG_INFO, "Allowing connections from: %s\n", allowed_hosts);
1430 }
1431
1432 int wait_conn_fork(int sock)
1433 {
1434 #ifdef HAVE_SIGACTION
1435 struct sigaction sig_action;
1436 #endif
1437 pid_t pid;
1438
1439 /* child process should handle the connection */
1440 pid = fork();
1441
1442 if (pid > 0) {
1443 close(sock); /* parent doesn't need the new connection */
1444 waitpid(pid, NULL, 0); /* parent waits for first child to exit */
1445 return TRUE; /* tell caller this is the parent process */
1446 }
1447
1448 if (pid < 0) {
1449 logit(LOG_ERR, "fork() failed with error %d, bailing out...", errno);
1450 exit(STATE_CRITICAL);
1451 }
1452
1453 /* fork again so we don't create zombies */
1454 pid = fork();
1455
1456 if (pid < 0) {
1457 logit(LOG_ERR, "Second fork() failed with error %d, bailing out...", errno);
1458 exit(STATE_CRITICAL);
1459 }
1460
1461 if (pid > 0) {
1462 /* first child returns immediately, grandchild is inherited by
1463 INIT process -> no zombies... */
1464 exit(STATE_OK);
1465 }
1466
1467 /* hey, there was an error... */
1468 if (sock < 0) {
1469 /* log error */
1470 logit(LOG_ERR, "Network server accept failure (%d: %s)",
1471 errno, strerror(errno));
1472 exit(STATE_OK);
1473 }
1474
1475 /* all good - handle signals */
1476 #ifdef HAVE_SIGACTION
1477 sig_action.sa_sigaction = NULL;
1478 sig_action.sa_handler = child_sighandler;
1479 sigfillset(&sig_action.sa_mask);
1480 sig_action.sa_flags = SA_NODEFER | SA_RESTART;
1481 sigaction(SIGQUIT, &sig_action, NULL);
1482 sigaction(SIGTERM, &sig_action, NULL);
1483 sigaction(SIGHUP, &sig_action, NULL);
1484 #else /* HAVE_SIGACTION */
1485 signal(SIGQUIT, child_sighandler);
1486 signal(SIGTERM, child_sighandler);
1487 signal(SIGHUP, child_sighandler);
1488 #endif /* HAVE_SIGACTION */
1489
1490 close_listen_socks(); /* grandchild does not need to listen */
1491
1492 return FALSE; /* tell caller this isn't the parent process */
1493 }
1494
1495 void conn_check_peer(int sock)
1496 {
1497 #ifdef HAVE_LIBWRAP
1498 struct request_info req;
1499 #endif
1500 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1501 struct sockaddr_storage addr;
1502 #else
1503 struct sockaddr addr;
1504 #endif
1505 struct sockaddr_in *nptr;
1506 struct sockaddr_in6 *nptr6;
1507
1508 char ipstr[INET6_ADDRSTRLEN];
1509 socklen_t addrlen;
1510 int rc;
1511
1512 /* find out who just connected... */
1513 addrlen = sizeof(addr);
1514 rc = getpeername(sock, (struct sockaddr *)&addr, &addrlen);
1515
1516 if (rc < 0) {
1517 /* log error */
1518 logit(LOG_ERR, "Error: Network server getpeername() failure (%d: %s)",
1519 errno, strerror(errno));
1520
1521 /* close socket prior to exiting */
1522 close(sock);
1523 return;
1524 }
1525
1526 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1527 switch (addr.ss_family) {
1528 #else
1529 switch (addr.sa_family) {
1530 #endif
1531
1532 case AF_INET:
1533 nptr = (struct sockaddr_in *)&addr;
1534 strncpy(remote_host, inet_ntoa(nptr->sin_addr), sizeof(remote_host) - 1);
1535 remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
1536 break;
1537
1538 case AF_INET6:
1539 nptr6 = (struct sockaddr_in6 *)&addr;
1540 if (inet_ntop(AF_INET6, (const void *)&(nptr6->sin6_addr),
1541 ipstr, sizeof(ipstr)) == NULL) {
1542 strncpy(ipstr, "Unknown", sizeof(ipstr));
1543 }
1544 strncpy(remote_host, ipstr, sizeof(remote_host) - 1);
1545 remote_host[MAX_HOST_ADDRESS_LENGTH - 1] = '\0';
1546 break;
1547 }
1548
1549 if (debug == TRUE)
1550 logit(LOG_INFO, "CONN_CHECK_PEER: checking if host is allowed: %s port %d\n",
1551 remote_host, nptr->sin_port);
1552
1553 /* is this host allowed? */
1554 if (allowed_hosts) {
1555 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE
1556 switch (addr.ss_family) {
1557 #else
1558 switch (addr.sa_family) {
1559 #endif
1560
1561 case AF_INET:
1562 /* log info */
1563 if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr))
1564 logit(LOG_DEBUG, "Connection from %s port %d", remote_host, nptr->sin_port);
1565
1566 if (!is_an_allowed_host(AF_INET, (void *)&(nptr->sin_addr))) {
1567 /* log error */
1568 logit(LOG_ERR, "Host %s is not allowed to talk to us!", remote_host);
1569
1570 /* log info */
1571 if (debug == TRUE)
1572 logit(LOG_DEBUG, "Connection from %s closed.", remote_host);
1573
1574 /* close socket prior to exiting */
1575 close(sock);
1576 exit(STATE_OK);
1577
1578 } else {
1579
1580 /* log info */
1581 if (debug == TRUE) {
1582 logit(LOG_DEBUG, "Host address is in allowed_hosts");
1583 }
1584
1585 }
1586 break;
1587
1588 case AF_INET6:
1589 /* log info */
1590 strcpy(remote_host, ipstr);
1591 if (debug == TRUE || (sslprm.log_opts & SSL_LogIpAddr)) {
1592 logit(LOG_DEBUG, "Connection from %s port %d", ipstr, nptr6->sin6_port);
1593 }
1594
1595 if (!is_an_allowed_host(AF_INET6, (void *)&(nptr6->sin6_addr))) {
1596 /* log error */
1597 logit(LOG_ERR, "Host %s is not allowed to talk to us!", ipstr);
1598
1599 /* log info */
1600 if (debug == TRUE)
1601 logit(LOG_DEBUG, "Connection from %s closed.", ipstr);
1602
1603 /* close socket prior to exiting */
1604 close(sock);
1605 exit(STATE_OK);
1606
1607 } else {
1608 /* log info */
1609 if (debug == TRUE)
1610 logit(LOG_DEBUG, "Host address is in allowed_hosts");
1611 }
1612 break;
1613 }
1614 }
1615
1616 #ifdef HAVE_LIBWRAP
1617 /* Check whether or not connections are allowed from this host */
1618 request_init(&req, RQ_DAEMON, "nrpe", RQ_FILE, sock, 0);
1619 fromhost(&req);
1620
1621 if (!hosts_access(&req)) {
1622 logit(LOG_DEBUG, "Connection refused by TCP wrapper");
1623 refuse(&req); /* refuse the connection */
1624 /* should not be reached */
1625 logit(LOG_ERR, "libwrap refuse() returns!");
1626 close(sock);
1627 exit(STATE_CRITICAL);
1628 }
1629 #endif
1630 }
1631
1632 /* handles a client connection */
1633 void handle_connection(int sock)
1634 {
1635 u_int32_t calculated_crc32;
1636 command *temp_command;
1637 v2_packet receive_packet, send_packet;
1638 v3_packet *v3_receive_packet = NULL, *v3_send_packet = NULL;
1639 int bytes_to_send;
1640 char buffer[MAX_INPUT_BUFFER], *send_buff = NULL, *send_pkt;
1641 char raw_command[MAX_INPUT_BUFFER];
1642 char processed_command[MAX_INPUT_BUFFER];
1643 int result = STATE_OK;
1644 int early_timeout = FALSE;
1645 int rc;
1646 int x;
1647 int32_t pkt_size;
1648 #ifdef DEBUG
1649 FILE *errfp;
1650 #endif
1651 #ifdef HAVE_SSL
1652 SSL *ssl = NULL;
1653 #endif
1654
1655 /* do SSL handshake */
1656 #ifdef HAVE_SSL
1657 if (use_ssl == TRUE) {
1658 if ((ssl = SSL_new(ctx)) == NULL) {
1659 logit(LOG_ERR, "Error: Could not create SSL connection structure.");
1660 # ifdef DEBUG
1661 errfp = fopen("/tmp/err.log", "a");
1662 ERR_print_errors_fp(errfp);
1663 fclose(errfp);
1664 # endif
1665 return;
1666 }
1667
1668 if (handle_conn_ssl(sock, ssl) != OK)
1669 return;
1670 }
1671 #endif
1672
1673 #ifdef HAVE_SSL
1674 rc = read_packet(sock, ssl, &receive_packet, &v3_receive_packet);
1675 #else
1676 rc = read_packet(sock, NULL, &receive_packet, &v3_receive_packet);
1677 #endif
1678
1679 /* disable connection alarm - a new alarm will be setup during my_system */
1680 alarm(0);
1681
1682 /* recv() error or client disconnect */
1683 if (rc <= 0) {
1684 /* log error */
1685 logit(LOG_ERR, "Could not read request from client %s, bailing out...", remote_host);
1686 if (v3_receive_packet)
1687 free(v3_receive_packet);
1688 #ifdef HAVE_SSL
1689 if (ssl) {
1690 complete_SSL_shutdown(ssl);
1691 SSL_free(ssl);
1692 logit(LOG_INFO, "INFO: SSL Socket Shutdown.\n");
1693 }
1694 #endif
1695 return;
1696 }
1697
1698 /* make sure the request is valid */
1699 if (validate_request(&receive_packet, v3_receive_packet) == ERROR) {
1700 /* log an error */
1701 logit(LOG_ERR, "Client request from %s was invalid, bailing out...", remote_host);
1702
1703 /* free memory */
1704 free(command_name);
1705 command_name = NULL;
1706 for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
1707 free(macro_argv[x]);
1708 macro_argv[x] = NULL;
1709 }
1710 if (v3_receive_packet)
1711 free(v3_receive_packet);
1712
1713 #ifdef HAVE_SSL
1714 if (ssl) {
1715 complete_SSL_shutdown(ssl);
1716 SSL_free(ssl);
1717 }
1718 #endif
1719
1720 return;
1721 }
1722
1723 /* log info */
1724 if (debug == TRUE)
1725 logit(LOG_DEBUG, "Host %s is asking for command '%s' to be run...",
1726 remote_host, command_name);
1727
1728 /* if this is the version check command, just spew it out */
1729 if (!strcmp(command_name, NRPE_HELLO_COMMAND)) {
1730 snprintf(buffer, sizeof(buffer), "NRPE v%s", PROGRAM_VERSION);
1731 buffer[sizeof(buffer) - 1] = '\x0';
1732 if (debug == TRUE) /* log info */
1733 logit(LOG_DEBUG, "Response to %s: %s", remote_host, buffer);
1734 if (v3_receive_packet)
1735 send_buff = strdup(buffer);
1736 else {
1737 send_buff = calloc(1, sizeof(buffer));
1738 strcpy(send_buff, buffer);
1739 }
1740 result = STATE_OK;
1741
1742 } else {
1743
1744 /* find the command we're supposed to run */
1745 temp_command = find_command(command_name);
1746 if (temp_command == NULL) {
1747 snprintf(buffer, sizeof(buffer), "NRPE: Command '%s' not defined", command_name);
1748 buffer[sizeof(buffer) - 1] = '\x0';
1749 if (debug == TRUE) /* log error */
1750 logit(LOG_DEBUG, "%s", buffer);
1751 if (v3_receive_packet)
1752 send_buff = strdup(buffer);
1753 else {
1754 send_buff = calloc(1, sizeof(buffer));
1755 strcpy(send_buff, buffer);
1756 }
1757 result = STATE_UNKNOWN;
1758
1759 } else {
1760
1761 /* process command line */
1762 if (command_prefix == NULL)
1763 strncpy(raw_command, temp_command->command_line, sizeof(raw_command) - 1);
1764 else
1765 snprintf(raw_command, sizeof(raw_command) - 1, "%s %s", command_prefix,
1766 temp_command->command_line);
1767 raw_command[sizeof(raw_command) - 1] = '\x0';
1768 process_macros(raw_command, processed_command, sizeof(processed_command));
1769
1770 if (debug == TRUE) /* log info */
1771 logit(LOG_DEBUG, "Running command: %s", processed_command);
1772
1773 /* run the command */
1774 strcpy(buffer, "");
1775 result = my_system(processed_command, command_timeout, &early_timeout, &send_buff);
1776
1777 if (debug == TRUE) /* log debug info */
1778 logit(LOG_DEBUG, "Command completed with return code %d and output: %s",
1779 result, send_buff);
1780
1781 /* see if the command timed out */
1782 if (early_timeout == TRUE) {
1783 sprintf(send_buff, "NRPE: Command timed out after %d seconds\n",
1784 command_timeout);
1785 result = STATE_UNKNOWN;
1786 } else if (!strcmp(send_buff, "")) {
1787 sprintf(send_buff, "NRPE: Unable to read output\n");
1788 result = STATE_UNKNOWN;
1789 }
1790
1791 /* check return code bounds */
1792 if ((result < 0) || (result > 3)) {
1793 /* log error */
1794 logit(LOG_ERR, "Bad return code for [%s]: %d", send_buff, result);
1795 result = STATE_UNKNOWN;
1796 }
1797 }
1798 }
1799
1800 /* free memory */
1801 free(command_name);
1802 command_name = NULL;
1803 for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
1804 free(macro_argv[x]);
1805 macro_argv[x] = NULL;
1806 }
1807 if (v3_receive_packet)
1808 free(v3_receive_packet);
1809 pkt_size = strlen(send_buff);
1810 /* strip newline character from end of output buffer */
1811 if (send_buff[strlen(send_buff) - 1] == '\n')
1812 send_buff[strlen(send_buff) - 1] = '\x0';
1813
1814 if (packet_ver == NRPE_PACKET_VERSION_2) {
1815 pkt_size = sizeof(v2_packet);
1816 send_pkt = (char *)&send_packet;
1817
1818 /* clear the response packet buffer */
1819 memset(&send_packet, 0, sizeof(send_packet));
1820 /* fill the packet with semi-random data */
1821 randomize_buffer((char *)&send_packet, sizeof(send_packet));
1822
1823 /* initialize response packet data */
1824 send_packet.packet_version = htons(packet_ver);
1825 send_packet.packet_type = htons(RESPONSE_PACKET);
1826 send_packet.result_code = htons(result);
1827 strncpy(&send_packet.buffer[0], send_buff, MAX_PACKETBUFFER_LENGTH);
1828 send_packet.buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
1829
1830 /* calculate the crc 32 value of the packet */
1831 send_packet.crc32_value = 0;
1832 calculated_crc32 = calculate_crc32((char *)&send_packet, sizeof(send_packet));
1833 send_packet.crc32_value = htonl(calculated_crc32);
1834
1835 } else {
1836
1837 pkt_size = (sizeof(v3_packet) - 1) + strlen(send_buff);
1838 v3_send_packet = calloc(1, pkt_size);
1839 send_pkt = (char *)v3_send_packet;
1840 /* initialize response packet data */
1841 v3_send_packet->packet_version = htons(packet_ver);
1842 v3_send_packet->packet_type = htons(RESPONSE_PACKET);
1843 v3_send_packet->result_code = htons(result);
1844 v3_send_packet->alignment = 0;
1845 v3_send_packet->buffer_length = htonl(strlen(send_buff));
1846 strcpy(&v3_send_packet->buffer[0], send_buff);
1847
1848 /* calculate the crc 32 value of the packet */
1849 v3_send_packet->crc32_value = 0;
1850 calculated_crc32 = calculate_crc32((char *)v3_send_packet, pkt_size);
1851 v3_send_packet->crc32_value = htonl(calculated_crc32);
1852 }
1853
1854 /* send the response back to the client */
1855 bytes_to_send = pkt_size;
1856 if (use_ssl == FALSE)
1857 sendall(sock, send_pkt, &bytes_to_send);
1858 #ifdef HAVE_SSL
1859 else
1860 SSL_write(ssl, send_pkt, bytes_to_send);
1861 #endif
1862
1863 #ifdef HAVE_SSL
1864 if (ssl) {
1865 complete_SSL_shutdown(ssl);
1866 SSL_free(ssl);
1867 }
1868 #endif
1869
1870 if (v3_send_packet)
1871 free(v3_send_packet);
1872
1873 /* log info */
1874 if (debug == TRUE)
1875 logit(LOG_DEBUG, "Return Code: %d, Output: %s", result, send_buff);
1876
1877 free(send_buff);
1878
1879 return;
1880 }
1881
1882 void init_handle_conn(void)
1883 {
1884 #ifdef HAVE_SIGACTION
1885 struct sigaction sig_action;
1886 #endif
1887
1888 /* log info */
1889 if (debug == TRUE)
1890 logit(LOG_DEBUG, "Handling the connection...");
1891
1892 /* set connection handler */
1893 #ifdef HAVE_SIGACTION
1894 sig_action.sa_sigaction = NULL;
1895 sig_action.sa_handler = my_connection_sighandler;
1896 sigfillset(&sig_action.sa_mask);
1897 sig_action.sa_flags = SA_NODEFER | SA_RESTART;
1898 sigaction(SIGALRM, &sig_action, NULL);
1899 #else
1900 signal(SIGALRM, my_connection_sighandler);
1901 #endif /* HAVE_SIGACTION */
1902 alarm(connection_timeout);
1903 }
1904
1905 int handle_conn_ssl(int sock, void *ssl_ptr)
1906 {
1907 #ifdef HAVE_SSL
1908 # if (defined(__sun) && defined(SOLARIS_10)) || defined(_AIX) || defined(__hpux)
1909 SSL_CIPHER *c;
1910 #else
1911 const SSL_CIPHER *c;
1912 #endif
1913 const char *errmsg = NULL;
1914 char buffer[MAX_INPUT_BUFFER];
1915 SSL *ssl = (SSL*)ssl_ptr;
1916 X509 *peer;
1917 int rc, x;
1918
1919 SSL_set_fd(ssl, sock);
1920
1921 /* keep attempting the request if needed */
1922 while (((rc = SSL_accept(ssl)) != 1)
1923 && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ));
1924
1925 if (rc != 1) {
1926 /* oops, got an unrecoverable error -- get out */
1927 if (sslprm.log_opts & (SSL_LogCertDetails | SSL_LogIfClientCert)) {
1928 int nerrs = 0;
1929 rc = 0;
1930 while ((x = ERR_get_error_line_data(NULL, NULL, NULL, NULL)) != 0) {
1931 errmsg = ERR_reason_error_string(x);
1932 logit(LOG_ERR, "Error: (ERR_get_error_line_data = %d), Could not complete SSL handshake with %s: %s", x, remote_host, errmsg);
1933
1934 if (errmsg && !strcmp(errmsg, "no shared cipher") && (sslprm.cert_file == NULL || sslprm.cacert_file == NULL))
1935 logit(LOG_ERR, "Error: This could be because you have not specified certificate or ca-certificate files");
1936
1937 ++nerrs;
1938 }
1939
1940 if (nerrs == 0) {
1941 logit(LOG_ERR, "Error: (nerrs = 0) Could not complete SSL handshake with %s: %d", remote_host, SSL_get_error(ssl, rc));
1942 }
1943 } else {
1944 logit(LOG_ERR, "Error: (!log_opts) Could not complete SSL handshake with %s: %d", remote_host, SSL_get_error(ssl, rc));
1945 }
1946 # ifdef DEBUG
1947 errfp = fopen("/tmp/err.log", "a");
1948 ERR_print_errors_fp(errfp);
1949 fclose(errfp);
1950 # endif
1951 return ERROR;
1952 }
1953
1954 /* successful handshake */
1955 if (sslprm.log_opts & SSL_LogVersion)
1956 logit(LOG_NOTICE, "Remote %s - SSL Version: %s", remote_host, SSL_get_version(ssl));
1957
1958 if (sslprm.log_opts & SSL_LogCipher) {
1959 c = SSL_get_current_cipher(ssl);
1960 logit(LOG_NOTICE, "Remote %s - %s, Cipher is %s", remote_host, SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
1961 }
1962
1963 if ((sslprm.log_opts & SSL_LogIfClientCert)
1964 || (sslprm.log_opts & SSL_LogCertDetails)) {
1965
1966
1967 peer = SSL_get_peer_certificate(ssl);
1968
1969 if (peer) {
1970 if (sslprm.log_opts & SSL_LogIfClientCert)
1971 logit(LOG_NOTICE, "SSL Client %s has %s certificate",
1972 remote_host, SSL_get_verify_result(ssl) == X509_V_OK ? "a valid" : "an invalid");
1973
1974 if (sslprm.log_opts & SSL_LogCertDetails) {
1975
1976 X509_NAME_oneline(X509_get_subject_name(peer), buffer, sizeof(buffer));
1977 logit(LOG_NOTICE, "SSL Client %s Cert Name: %s",
1978 remote_host, buffer);
1979
1980 X509_NAME_oneline(X509_get_issuer_name(peer), buffer, sizeof(buffer));
1981 logit(LOG_NOTICE, "SSL Client %s Cert Issuer: %s",
1982 remote_host, buffer);
1983 }
1984
1985 } else if (sslprm.client_certs == 0)
1986 logit(LOG_NOTICE, "SSL Not asking for client certification");
1987
1988 else
1989 logit(LOG_NOTICE, "SSL Client %s did not present a certificate",
1990 remote_host);
1991 }
1992 #endif
1993
1994 return OK;
1995 }
1996
1997 int read_packet(int sock, void *ssl_ptr, v2_packet * v2_pkt, v3_packet ** v3_pkt)
1998 {
1999 int32_t common_size, tot_bytes, bytes_to_recv, buffer_size;
2000 int rc;
2001 char *buff_ptr;
2002
2003 /* Read only the part that's common between versions 2 & 3 */
2004 common_size = tot_bytes = bytes_to_recv = (char *)&v2_pkt->buffer - (char *)v2_pkt;
2005
2006 if (use_ssl == FALSE) {
2007 rc = recvall(sock, (char *)v2_pkt, &tot_bytes, socket_timeout);
2008
2009 if (rc <= 0 || rc != bytes_to_recv)
2010 return -1;
2011
2012 packet_ver = ntohs(v2_pkt->packet_version);
2013 if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
2014 logit(LOG_ERR, "Error: (use_ssl == false): Request packet version was invalid!");
2015 return -1;
2016 }
2017
2018 if (packet_ver == NRPE_PACKET_VERSION_2) {
2019 buffer_size = sizeof(v2_packet) - common_size;
2020 buff_ptr = (char *)v2_pkt + common_size;
2021
2022 } else {
2023 int32_t pkt_size = sizeof(v3_packet) - 1;
2024
2025 /* Read the alignment filler */
2026 bytes_to_recv = sizeof(int16_t);
2027 rc = recvall(sock, (char *)&buffer_size, &bytes_to_recv, socket_timeout);
2028 if (rc <= 0 || bytes_to_recv != sizeof(int16_t))
2029 return -1;
2030 tot_bytes += rc;
2031
2032 /* Read the buffer size */
2033 bytes_to_recv = sizeof(buffer_size);
2034 rc = recvall(sock, (char *)&buffer_size, &bytes_to_recv, socket_timeout);
2035 if (rc <= 0 || bytes_to_recv != sizeof(buffer_size))
2036 return -1;
2037 tot_bytes += rc;
2038
2039 buffer_size = ntohl(buffer_size);
2040 pkt_size += buffer_size;
2041 if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
2042 logit(LOG_ERR, "Error: (use_ssl == false): Could not allocate memory for packet");
2043 return -1;
2044 }
2045
2046 memcpy(*v3_pkt, v2_pkt, common_size);
2047 (*v3_pkt)->buffer_length = htonl(buffer_size);
2048 buff_ptr = (*v3_pkt)->buffer;
2049 }
2050
2051 bytes_to_recv = buffer_size;
2052 rc = recvall(sock, buff_ptr, &bytes_to_recv, socket_timeout);
2053
2054 if (rc <= 0 || rc != buffer_size) {
2055 if (packet_ver == NRPE_PACKET_VERSION_3) {
2056 free(*v3_pkt);
2057 *v3_pkt = NULL;
2058 }
2059 return -1;
2060 } else
2061 tot_bytes += rc;
2062 }
2063 #ifdef HAVE_SSL
2064 else {
2065 SSL *ssl = (SSL *) ssl_ptr;
2066
2067 while (((rc = SSL_read(ssl, v2_pkt, bytes_to_recv)) <= 0)
2068 && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2069 }
2070
2071 if (rc <= 0 || rc != bytes_to_recv)
2072 return -1;
2073
2074 packet_ver = ntohs(v2_pkt->packet_version);
2075 if (packet_ver != NRPE_PACKET_VERSION_2 && packet_ver != NRPE_PACKET_VERSION_3) {
2076 logit(LOG_ERR, "Error: (use_ssl == true): Request packet version was invalid!");
2077 return -1;
2078 }
2079
2080 if (packet_ver == NRPE_PACKET_VERSION_2) {
2081 buffer_size = sizeof(v2_packet) - common_size;
2082 buff_ptr = (char *)v2_pkt + common_size;
2083 } else {
2084 int32_t pkt_size = sizeof(v3_packet) - 1;
2085
2086 /* Read the alignment filler */
2087 bytes_to_recv = sizeof(int16_t);
2088 while (((rc = SSL_read(ssl, &buffer_size, bytes_to_recv)) <= 0)
2089 && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2090 }
2091
2092 if (rc <= 0 || bytes_to_recv != sizeof(int16_t))
2093 return -1;
2094 tot_bytes += rc;
2095
2096 /* Read the buffer size */
2097 bytes_to_recv = sizeof(buffer_size);
2098 while (((rc = SSL_read(ssl, &buffer_size, bytes_to_recv)) <= 0)
2099 && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2100 }
2101
2102 if (rc <= 0 || bytes_to_recv != sizeof(buffer_size))
2103 return -1;
2104 tot_bytes += rc;
2105
2106 buffer_size = ntohl(buffer_size);
2107 pkt_size += buffer_size;
2108 if ((*v3_pkt = calloc(1, pkt_size)) == NULL) {
2109 logit(LOG_ERR, "Error: (use_ssl == true): Could not allocate memory for packet");
2110 return -1;
2111 }
2112
2113 memcpy(*v3_pkt, v2_pkt, common_size);
2114 (*v3_pkt)->buffer_length = htonl(buffer_size);
2115 buff_ptr = (*v3_pkt)->buffer;
2116 }
2117
2118 bytes_to_recv = buffer_size;
2119 while (((rc = SSL_read(ssl, buff_ptr, bytes_to_recv)) <= 0)
2120 && (SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ)) {
2121 }
2122
2123 if (rc <= 0 || rc != buffer_size) {
2124 if (packet_ver == NRPE_PACKET_VERSION_3) {
2125 free(*v3_pkt);
2126 *v3_pkt = NULL;
2127 }
2128 return -1;
2129 } else
2130 tot_bytes += rc;
2131 }
2132 #endif
2133
2134 return tot_bytes;
2135 }
2136
2137 /* free all allocated memory */
2138 void free_memory(void)
2139 {
2140 command *this_command;
2141 command *next_command;
2142
2143 /* free memory for the command list */
2144 this_command = command_list;
2145 while (this_command != NULL) {
2146 next_command = this_command->next;
2147 if (this_command->command_name)
2148 free(this_command->command_name);
2149 if (this_command->command_line)
2150 free(this_command->command_line);
2151 free(this_command);
2152 this_command = next_command;
2153 }
2154
2155 command_list = NULL;
2156 return;
2157 }
2158
2159 /* executes a system command via popen(), but protects against timeouts */
2160 int my_system(char *command, int timeout, int *early_timeout, char **output)
2161 {
2162 FILE *fp;
2163 pid_t pid;
2164 time_t start_time, end_time;
2165 int status;
2166 int result;
2167 char buffer[MAX_INPUT_BUFFER];
2168 int fd[2];
2169 int bytes_read = 0, tot_bytes = 0;
2170 int output_size;
2171 #ifdef HAVE_SIGACTION
2172 struct sigaction sig_action;
2173 #endif
2174
2175 *early_timeout = FALSE; /* initialize return variables */
2176
2177 if (command == NULL) /* if no command was passed, return with no error */
2178 return STATE_OK;
2179
2180 /* make sure that we are within max_commands boundaries before attempting */
2181 if (max_commands != 0) {
2182 while (commands_running >= max_commands) {
2183 logit(LOG_WARNING, "Commands choked. Sleeping 1s - commands_running: %d, max_commands: %d", commands_running, max_commands);
2184 sleep(1);
2185 }
2186 }
2187
2188 /* create a pipe */
2189 if (pipe(fd) == -1) {
2190 logit(LOG_ERR, "ERROR: pipe(): %s, bailing out...", strerror(errno));
2191 exit(STATE_CRITICAL);
2192 }
2193
2194 /* make the pipe non-blocking */
2195 fcntl(fd[0], F_SETFL, O_NONBLOCK);
2196 fcntl(fd[1], F_SETFL, O_NONBLOCK);
2197
2198 time(&start_time); /* get the command start time */
2199
2200 pid = fork(); /* fork */
2201
2202 /* return an error if we couldn't fork */
2203 if (pid == -1) {
2204 snprintf(buffer, sizeof(buffer) - 1, "NRPE: Call to fork() failed\n");
2205 buffer[sizeof(buffer) - 1] = '\x0';
2206
2207 if (packet_ver == NRPE_PACKET_VERSION_2) {
2208 int output_size = sizeof(v2_packet);
2209 *output = calloc(1, output_size);
2210 strncpy(*output, buffer, output_size - 1);
2211 *output[output_size - 1] = '\0';
2212 } else
2213 *output = strdup(buffer);
2214
2215 /* close both ends of the pipe */
2216 close(fd[0]);
2217 close(fd[1]);
2218
2219 return STATE_UNKNOWN;
2220 }
2221
2222 /* execute the command in the child process */
2223 if (pid == 0) {
2224
2225 /* get root back so the next call works correctly */
2226 if (SETEUID(0) == -1 && debug)
2227 logit(LOG_WARNING, "WARNING: my_system() seteuid(0): %s", strerror(errno));
2228
2229 drop_privileges(nrpe_user, nrpe_group, 1); /* drop privileges */
2230 close(fd[0]); /* close pipe for reading */
2231 setpgid(0, 0); /* become process group leader */
2232
2233 /* trap commands that timeout */
2234 #ifdef HAVE_SIGACTION
2235 sig_action.sa_sigaction = NULL;
2236 sig_action.sa_handler = my_system_sighandler;
2237 sigfillset(&sig_action.sa_mask);
2238 sig_action.sa_flags = SA_NODEFER | SA_RESTART;
2239 sigaction(SIGALRM, &sig_action, NULL);
2240 #else
2241 signal(SIGALRM, my_system_sighandler);
2242 #endif /* HAVE_SIGACTION */
2243 alarm(timeout);
2244
2245 fp = popen(command, "r"); /* run the command */
2246
2247 /* report an error if we couldn't run the command */
2248 if (fp == NULL) {
2249 strncpy(buffer, "NRPE: Call to popen() failed\n", sizeof(buffer) - 1);
2250 buffer[sizeof(buffer) - 1] = '\x0';
2251
2252 /* write the error back to the parent process */
2253 if (write(fd[1], buffer, strlen(buffer) + 1) == -1)
2254 logit(LOG_ERR, "ERROR: my_system() write(fd, buffer)-1 failed...");
2255
2256 result = STATE_CRITICAL;
2257
2258 } else {
2259
2260 /* read all lines of output - supports Nagios 3.x multiline output */
2261 while ((bytes_read = fread(buffer, 1, sizeof(buffer) - 1, fp)) > 0) {
2262 /* write the output back to the parent process */
2263 if (write(fd[1], buffer, bytes_read) == -1)
2264 logit(LOG_ERR, "ERROR: my_system() write(fd, buffer)-2 failed...");
2265 }
2266
2267 if (write(fd[1], "\0", 1) == -1)
2268 logit(LOG_ERR, "ERROR: my_system() write(fd, NULL) failed...");
2269
2270 status = pclose(fp); /* close the command and get termination status */
2271
2272 /* report an error if we couldn't close the command */
2273 if (status == -1)
2274 result = STATE_CRITICAL;
2275 else if (!WIFEXITED(status))
2276 /* report an error if child died due to signal (Klas Lindfors) */
2277 result = STATE_CRITICAL;
2278 else
2279 result = WEXITSTATUS(status);
2280 }
2281
2282 close(fd[1]); /* close pipe for writing */
2283 alarm(0); /* reset the alarm */
2284 exit(result); /* return plugin exit code to parent process */
2285
2286 } else {
2287 /* parent waits for child to finish executing command */
2288
2289 commands_running++;
2290
2291 close(fd[1]); /* close pipe for writing */
2292 waitpid(pid, &status, 0); /* wait for child to exit */
2293 time(&end_time); /* get the end time for running the command */
2294 result = WEXITSTATUS(status); /* get the exit code returned from the program */
2295
2296 /* because of my idiotic idea of having UNKNOWN states be equivalent to -1, I must hack things a bit... */
2297 if (result == 255)
2298 result = STATE_UNKNOWN;
2299
2300 /* check bounds on the return value */
2301 if (result < 0 || result > 3)
2302 result = STATE_UNKNOWN;
2303
2304 if (packet_ver == NRPE_PACKET_VERSION_2) {
2305 output_size = sizeof(v2_packet);
2306 *output = calloc(1, output_size);
2307 } else {
2308 output_size = 1024 * 64; /* Maximum buffer is 64K */
2309 *output = calloc(1, output_size);
2310 }
2311
2312 /* try and read the results from the command output (retry if we encountered a signal) */
2313 for (;;) {
2314 bytes_read = read(fd[0], buffer, sizeof(buffer) - 1);
2315 if (bytes_read == 0)
2316 break;
2317 if (bytes_read == -1) {
2318 if (errno == EINTR)
2319 continue;
2320 else
2321 break;
2322 }
2323 if (tot_bytes < output_size) /* If buffer is full, discard the rest */
2324 strncat(*output, buffer, output_size - tot_bytes - 1);
2325 tot_bytes += bytes_read;
2326 }
2327
2328 (*output)[output_size - 1] = '\0';
2329
2330 /* if there was a critical return code and no output AND the
2331 * command time exceeded the timeout thresholds, assume a timeout */
2332 if (result == STATE_CRITICAL && bytes_read == -1 && (end_time - start_time) >= timeout) {
2333 *early_timeout = TRUE;
2334
2335 /* send termination signal to child process group */
2336 kill((pid_t) (-pid), SIGTERM);
2337 kill((pid_t) (-pid), SIGKILL);
2338 }
2339
2340 close(fd[0]); /* close the pipe for reading */
2341
2342 commands_running--;
2343 }
2344
2345 #ifdef DEBUG
2346 printf("my_system() end\n");
2347 #endif
2348
2349 return result;
2350 }
2351
2352 /* handle timeouts when executing commands via my_system() */
2353 void my_system_sighandler(int sig)
2354 {
2355 exit(STATE_CRITICAL); /* force the child process to exit... */
2356 }
2357
2358 /* handle errors where connection takes too long */
2359 void my_connection_sighandler(int sig)
2360 {
2361 logit(LOG_ERR, "Connection has taken too long to establish. Exiting...");
2362 exit(STATE_CRITICAL);
2363 }
2364
2365 /* drops privileges */
2366 int drop_privileges(char *user, char *group, int full_drop)
2367 {
2368 uid_t uid = (uid_t)-1;
2369 gid_t gid = (gid_t)-1;
2370 struct group *grp;
2371 struct passwd *pw;
2372
2373 if (use_inetd == TRUE)
2374 return OK;
2375
2376 /* set effective group ID */
2377 if (group != NULL) {
2378
2379 /* see if this is a group name */
2380 if (strspn(group, "0123456789") < strlen(group)) {
2381 grp = (struct group *)getgrnam(group);
2382 if (grp != NULL)
2383 gid = (gid_t) (grp->gr_gid);
2384 else
2385 logit(LOG_ERR, "Warning: Could not get group entry for '%s'", group);
2386 endgrent();
2387
2388 } else
2389 /* else we were passed the GID */
2390 gid = (gid_t) atoi(group);
2391
2392 /* set effective group ID if other than current EGID */
2393 if (gid != getegid()) {
2394 if (setgid(gid) == -1)
2395 logit(LOG_ERR, "Warning: Could not set effective GID=%d", (int)gid);
2396 }
2397 }
2398
2399
2400 /* set effective user ID */
2401 if (user != NULL) {
2402
2403 /* see if this is a user name */
2404 if (strspn(user, "0123456789") < strlen(user)) {
2405 pw = (struct passwd *)getpwnam(user);
2406 if (pw != NULL)
2407 uid = (uid_t) (pw->pw_uid);
2408 else
2409 logit(LOG_ERR, "Warning: Could not get passwd entry for '%s'", user);
2410 endpwent();
2411
2412 } else
2413 /* else we were passed the UID */
2414 uid = (uid_t) atoi(user);
2415
2416 if (uid != geteuid()) {
2417 /* set effective user ID if other than current EUID */
2418 #ifdef HAVE_INITGROUPS
2419 /* initialize supplementary groups */
2420 if (initgroups(user, gid) == -1) {
2421 if (errno == EPERM)
2422 logit(LOG_ERR, "Warning: Unable to change supplementary groups using initgroups()");
2423 else {
2424 logit(LOG_ERR, "Warning: Possibly root user failed dropping privileges with initgroups()");
2425 return ERROR;
2426 }
2427 }
2428 #endif
2429
2430 if (full_drop) {
2431 if (setuid(uid) == -1)
2432 logit(LOG_ERR, "Warning: Could not set UID=%d", (int)uid);
2433 } else if (SETEUID(uid) == -1)
2434 logit(LOG_ERR, "Warning: Could not set effective UID=%d", (int)uid);
2435 }
2436 }
2437
2438 return OK;
2439 }
2440
2441 /* write an optional pid file */
2442 int write_pid_file(void)
2443 {
2444 int fd;
2445 int result = 0;
2446 pid_t pid = 0;
2447 char pbuf[16];
2448
2449 /* no pid file was specified */
2450 if (pid_file == NULL)
2451 return OK;
2452
2453 /* read existing pid file */
2454 if ((fd = open(pid_file, O_RDONLY)) >= 0) {
2455
2456 result = read(fd, pbuf, (sizeof pbuf) - 1);
2457 close(fd);
2458
2459 if (result > 0) {
2460 pbuf[result] = '\x0';
2461 pid = (pid_t) atoi(pbuf);
2462
2463 /* if previous process is no longer running running, remove the old pid file */
2464 if (pid && (pid == getpid() || kill(pid, 0) < 0))
2465 unlink(pid_file);
2466
2467 else {
2468 /* previous process is still running */
2469 logit(LOG_ERR, "There's already an NRPE server running (PID %lu). Bailing out...", (unsigned long)pid);
2470 return ERROR;
2471 }
2472 }
2473 }
2474
2475 /* write new pid file */
2476 if ((fd = open(pid_file, O_WRONLY | O_CREAT, 0644)) >= 0) {
2477 sprintf(pbuf, "%d\n", (int)getpid());
2478
2479 if (write(fd, pbuf, strlen(pbuf)) == -1)
2480 logit(LOG_ERR, "ERROR: write_pid_file() write(fd, pbuf) failed...");
2481
2482 close(fd);
2483 wrote_pid_file = TRUE;
2484 } else {
2485 logit(LOG_ERR, "Cannot write to pidfile '%s' - check your privileges.", pid_file);
2486 return ERROR;
2487 }
2488
2489 return OK;
2490 }
2491
2492 /* remove pid file */
2493 int remove_pid_file(void)
2494 {
2495 if (pid_file == NULL)
2496 return OK; /* no pid file was specified */
2497 if (wrote_pid_file == FALSE)
2498 return OK; /* pid file was not written */
2499
2500 /* get root back so we can delete the pid file */
2501 if (SETEUID(0) == -1 && debug)
2502 logit(LOG_WARNING, "WARNING: remove_pid_file() seteuid(0): %s", strerror(errno));
2503
2504 if (unlink(pid_file) == -1) {
2505 logit(LOG_ERR, "Cannot remove pidfile '%s' - check your privileges.", pid_file);
2506 return ERROR;
2507 }
2508
2509 return OK;
2510 }
2511
2512 #ifdef HAVE_SSL
2513
2514 void my_disconnect_sighandler(int sig)
2515 {
2516 logit(LOG_ERR, "SSL_shutdown() has taken too long to complete. Exiting now..");
2517 exit(STATE_CRITICAL);
2518 }
2519
2520 void complete_SSL_shutdown(SSL * ssl)
2521 {
2522 /* Thanks to Jari Takkala (jtakkala@gmail.com) for the following information.
2523
2524 We need to call SSL_shutdown() at least twice, otherwise we'll
2525 be left with data in the socket receive buffer, and the
2526 subsequent process termination will cause TCP RST's to be sent
2527 to the client.
2528
2529 See http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/32219/diff
2530 for more information.
2531 */
2532
2533 int x;
2534
2535 /* set disconnection handler */
2536 signal(SIGALRM, my_disconnect_sighandler);
2537 alarm(ssl_shutdown_timeout);
2538
2539 for (x = 0; x < 4; x++) {
2540 if (SSL_shutdown(ssl))
2541 break;
2542 }
2543
2544 alarm(0);
2545 }
2546 #endif /*HAVE_SSL */
2547
2548 /* bail if daemon is running as root */
2549 int check_privileges(void)
2550 {
2551 uid_t uid = geteuid();
2552 gid_t gid = getegid();
2553
2554 if (uid == 0 || gid == 0) {
2555 logit(LOG_ERR, "Error: NRPE daemon cannot be run as user/group root!");
2556 exit(STATE_CRITICAL);
2557 }
2558
2559 return OK;
2560 }
2561
2562 /* handle signals (parent process) */
2563 void sighandler(int sig)
2564 {
2565 static char *sigs[] = {
2566 "EXIT", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "BUS", "FPE",
2567 "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", "STKFLT",
2568 "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "URG", "XCPU",
2569 "XFSZ", "VTALRM", "PROF", "WINCH", "IO", "PWR", "UNUSED", "ZERR",
2570 "DEBUG", (char *)NULL
2571 };
2572 int i;
2573
2574 if (sig < 0)
2575 sig = -sig;
2576
2577 for (i = 0; sigs[i] != (char *)NULL; i++) ;
2578 sig %= i;
2579
2580 /* we received a SIGHUP, so restart... */
2581 if (sig == SIGHUP) {
2582 sigrestart = TRUE;
2583 logit(LOG_NOTICE, "Caught SIGHUP - restarting...\n");
2584 }
2585
2586 /* else begin shutting down... */
2587 if (sig == SIGTERM) {
2588 /* if shutdown is already true, we're in a signal trap loop! */
2589 if (sigshutdown == TRUE)
2590 exit(STATE_CRITICAL);
2591 sigshutdown = TRUE;
2592 logit(LOG_NOTICE, "Caught SIG%s - shutting down...\n", sigs[sig]);
2593 }
2594
2595 return;
2596 }
2597
2598 /* handle signals (child processes) */
2599 void child_sighandler(int sig)
2600 {
2601 exit(0); /* terminate */
2602 }
2603
2604 /* tests whether or not a client request is valid */
2605 int validate_request(v2_packet * v2pkt, v3_packet * v3pkt)
2606 {
2607 u_int32_t packet_crc32;
2608 u_int32_t calculated_crc32;
2609 char *buff, *ptr;
2610 int rc;
2611 #ifdef ENABLE_COMMAND_ARGUMENTS
2612 int x;
2613 #endif
2614
2615 /* check the crc 32 value */
2616 if (packet_ver == NRPE_PACKET_VERSION_3) {
2617 int32_t pkt_size = (sizeof(v3_packet) - 1) + ntohl(v3pkt->buffer_length);
2618 packet_crc32 = ntohl(v3pkt->crc32_value);
2619 v3pkt->crc32_value = 0L;
2620 v3pkt->alignment = 0;
2621 calculated_crc32 = calculate_crc32((char *)v3pkt, pkt_size);
2622 } else {
2623 packet_crc32 = ntohl(v2pkt->crc32_value);
2624 v2pkt->crc32_value = 0L;
2625 calculated_crc32 = calculate_crc32((char *)v2pkt, sizeof(v2_packet));
2626 }
2627
2628 if (packet_crc32 != calculated_crc32) {
2629 logit(LOG_ERR, "Error: Request packet had invalid CRC32.");
2630 return ERROR;
2631 }
2632
2633 /* make sure this is the right type of packet */
2634 if (ntohs(v2pkt->packet_type) != QUERY_PACKET) {
2635 logit(LOG_ERR, "Error: Request packet type was invalid!");
2636 return ERROR;
2637 }
2638
2639 /* make sure buffer is terminated */
2640 if (packet_ver == NRPE_PACKET_VERSION_3) {
2641 int32_t l = ntohs(v3pkt->buffer_length);
2642 v3pkt->buffer[l - 1] = '\x0';
2643 buff = v3pkt->buffer;
2644 } else {
2645 v2pkt->buffer[MAX_PACKETBUFFER_LENGTH - 1] = '\x0';
2646 buff = v2pkt->buffer;
2647 }
2648
2649 /* client must send some kind of request */
2650 if (buff[0] == '\0') {
2651 logit(LOG_ERR, "Error: Request contained no query!");
2652 return ERROR;
2653 }
2654
2655 /* make sure request doesn't contain nasties */
2656 if (packet_ver == NRPE_PACKET_VERSION_3)
2657 rc = contains_nasty_metachars(v3pkt->buffer);
2658 else
2659 rc = contains_nasty_metachars(v2pkt->buffer);
2660 if (rc == TRUE) {
2661 logit(LOG_ERR, "Error: Request contained illegal metachars!");
2662 return ERROR;
2663 }
2664
2665 /* make sure the request doesn't contain arguments */
2666 if (strchr(v2pkt->buffer, '!')) {
2667 #ifdef ENABLE_COMMAND_ARGUMENTS
2668 if (allow_arguments == FALSE) {
2669 logit(LOG_ERR, "Error: Request contained command arguments, but argument option is not enabled!");
2670 return ERROR;
2671 }
2672 #else
2673 logit(LOG_ERR, "Error: Request contained command arguments!");
2674 return ERROR;
2675 #endif
2676 }
2677
2678 /* get command name */
2679 #ifdef ENABLE_COMMAND_ARGUMENTS
2680 ptr = strtok(buff, "!");
2681 #else
2682 ptr = buff;
2683 #endif
2684 command_name = strdup(ptr);
2685 if (command_name == NULL) {
2686 logit(LOG_ERR, "Error: Memory allocation failed");
2687 return ERROR;
2688 }
2689 #ifdef ENABLE_COMMAND_ARGUMENTS
2690 /* get command arguments */
2691 if (allow_arguments == TRUE) {
2692
2693 for (x = 0; x < MAX_COMMAND_ARGUMENTS; x++) {
2694 ptr = strtok(NULL, "!");
2695 if (ptr == NULL)
2696 break;
2697 macro_argv[x] = strdup(ptr);
2698 if (macro_argv[x] == NULL) {
2699 logit(LOG_ERR, "Error: Memory allocation failed");
2700 return ERROR;
2701 }
2702 if (!strcmp(macro_argv[x], "")) {
2703 logit(LOG_ERR, "Error: Request contained an empty command argument");
2704 return ERROR;
2705 }
2706 if (strstr(macro_argv[x], "$(")) {
2707 # ifndef ENABLE_BASH_COMMAND_SUBSTITUTION
2708 logit(LOG_ERR, "Error: Request contained a bash command substitution!");
2709 return ERROR;
2710 # else
2711 if (FALSE == allow_bash_cmd_subst) {
2712 logit(LOG_ERR, "Error: Request contained a bash command substitution, but they are disallowed!");
2713 return ERROR;
2714 }
2715 # endif
2716 }
2717 }
2718 }
2719 #endif
2720 return OK;
2721 }
2722
2723 /* tests whether a buffer contains illegal metachars */
2724 int contains_nasty_metachars(char *str)
2725 {
2726 int result;
2727
2728 if (str == NULL)
2729 return FALSE;
2730
2731 result = strcspn(str, nasty_metachars);
2732 if (result != strlen(str))
2733 return TRUE;
2734
2735 return FALSE;
2736 }
2737
2738 /* replace macros in buffer */
2739 int process_macros(char *input_buffer, char *output_buffer, int buffer_length)
2740 {
2741 char *temp_buffer;
2742 int in_macro;
2743 int arg_index = 0;
2744 char *selected_macro = NULL;
2745
2746 strcpy(output_buffer, "");
2747
2748 in_macro = FALSE;
2749
2750 for (temp_buffer = my_strsep(&input_buffer, "$"); temp_buffer != NULL;
2751 temp_buffer = my_strsep(&input_buffer, "$")) {
2752
2753 selected_macro = NULL;
2754
2755 if (in_macro == FALSE) {
2756 if (strlen(output_buffer) + strlen(temp_buffer) < buffer_length - 1) {
2757 strncat(output_buffer, temp_buffer, buffer_length - strlen(output_buffer) - 1);
2758 output_buffer[buffer_length - 1] = '\x0';
2759 }
2760 in_macro = TRUE;
2761
2762 } else {
2763
2764 if (strlen(output_buffer) + strlen(temp_buffer) < buffer_length - 1) {
2765
2766 /* argument macro */
2767 if (strstr(temp_buffer, "ARG") == temp_buffer) {
2768 arg_index = atoi(temp_buffer + 3);
2769 if (arg_index >= 1 && arg_index <= MAX_COMMAND_ARGUMENTS)
2770 selected_macro = macro_argv[arg_index - 1];
2771
2772 } else if (!strcmp(temp_buffer, "")) {
2773 /* an escaped $ is done by specifying two $$ next to each other */
2774 strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
2775
2776 } else {
2777 /* a non-macro, just some user-defined string between two $s */
2778 strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
2779 output_buffer[buffer_length - 1] = '\x0';
2780 strncat(output_buffer, temp_buffer,
2781 buffer_length - strlen(output_buffer) - 1);
2782 output_buffer[buffer_length - 1] = '\x0';
2783 strncat(output_buffer, "$", buffer_length - strlen(output_buffer) - 1);
2784 }
2785
2786
2787 /* insert macro */
2788 if (selected_macro != NULL)
2789 strncat(output_buffer, (selected_macro == NULL) ? "" : selected_macro,
2790 buffer_length - strlen(output_buffer) - 1);
2791
2792 output_buffer[buffer_length - 1] = '\x0';
2793 }
2794
2795 in_macro = FALSE;
2796 }
2797 }
2798
2799 return OK;
2800 }
2801
2802 /* process command line arguments */
2803 int process_arguments(int argc, char **argv)
2804 {
2805 char optchars[MAX_INPUT_BUFFER];
2806 int c = 1;
2807 int have_mode = FALSE;
2808 #ifdef HAVE_GETOPT_LONG
2809 int option_index = 0;
2810 static struct option long_options[] = {
2811 {"config", required_argument, 0, 'c'},
2812 {"inetd", no_argument, 0, 'i'},
2813 /* To compatibility between short and long options but not used on AIX */
2814 {"src", no_argument, 0, 's'},
2815 {"no-forking", no_argument, 0, 'f'},
2816 {"4", no_argument, 0, '4'},
2817 {"ipv6", no_argument, 0, '6'},
2818 {"daemon", no_argument, 0, 'd'},
2819 {"no-ssl", no_argument, 0, 'n'},
2820 {"help", no_argument, 0, 'h'},
2821 {"license", no_argument, 0, 'l'},
2822 {"version", no_argument, 0, 'V'},
2823 {0, 0, 0, 0}
2824 };
2825 #endif
2826
2827 /* no options were supplied */
2828 if (argc < 2)
2829 return ERROR;
2830
2831 snprintf(optchars, MAX_INPUT_BUFFER, "c:hVldi46nsf");
2832
2833 while (1) {
2834 #ifdef HAVE_GETOPT_LONG
2835 c = getopt_long(argc, argv, optchars, long_options, &option_index);
2836 #else
2837 c = getopt(argc, argv, optchars);
2838 #endif
2839 if (c == -1 || c == EOF)
2840 break;
2841
2842 /* process all arguments */
2843 switch (c) {
2844
2845 case '?':
2846 case 'h':
2847 show_help = TRUE;
2848 break;
2849
2850 case 'V':
2851 show_version = TRUE;
2852 have_mode = TRUE;
2853 break;
2854
2855 case 'l':
2856 show_license = TRUE;
2857 break;
2858
2859 case 'c':
2860 strncpy(config_file, optarg, sizeof(config_file));
2861 config_file[sizeof(config_file) - 1] = '\x0';
2862 break;
2863
2864 case 'd':
2865 use_inetd = FALSE;
2866 have_mode = TRUE;
2867 break;
2868
2869 case 'i':
2870 use_inetd = TRUE;
2871 have_mode = TRUE;
2872 break;
2873
2874 case '4':
2875 address_family = AF_INET;
2876 break;
2877
2878 case '6':
2879 address_family = AF_INET6;
2880 break;
2881
2882 case 'n':
2883 use_ssl = FALSE;
2884 break;
2885
2886 case 's': /* Argument s to indicate SRC option */
2887 use_src = TRUE;
2888 have_mode = TRUE;
2889 break;
2890
2891 case 'f':
2892 use_inetd = FALSE;
2893 no_forking = TRUE;
2894 have_mode = TRUE;
2895 break;
2896
2897 default:
2898 return ERROR;
2899 }
2900 }
2901
2902 /* bail if we didn't get required args */
2903 if (have_mode == FALSE)
2904 return ERROR;
2905
2906 return OK;
2907 }
2908