1 /*****************************************************************************
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 $Id$
19 *****************************************************************************/
21 /* progname "check_tcp" changes depending on symlink called */
22 char *progname;
23 const char *revision = "$Revision$";
24 const char *copyright = "1999-2004";
25 const char *email = "nagiosplug-devel@lists.sourceforge.net";
27 #include "common.h"
28 #include "netutils.h"
29 #include "utils.h"
31 #ifdef HAVE_SSL_H
32 # include <rsa.h>
33 # include <crypto.h>
34 # include <x509.h>
35 # include <pem.h>
36 # include <ssl.h>
37 # include <err.h>
38 #else
39 # ifdef HAVE_OPENSSL_SSL_H
40 # include <openssl/rsa.h>
41 # include <openssl/crypto.h>
42 # include <openssl/x509.h>
43 # include <openssl/pem.h>
44 # include <openssl/ssl.h>
45 # include <openssl/err.h>
46 # endif
47 #endif
49 #ifdef HAVE_SSL
50 static int check_cert = FALSE;
51 static int days_till_exp;
52 static char *randbuff = "";
53 static SSL_CTX *ctx;
54 static SSL *ssl;
55 static X509 *server_cert;
56 static int connect_SSL (void);
57 static int check_certificate (X509 **);
58 # define my_recv(buf, len) ((flags & FLAG_SSL) ? SSL_read(ssl, buf, len) : read(sd, buf, len))
59 #else
60 # define my_recv(buf, len) read(sd, buf, len)
61 #endif
64 /* int my_recv(char *, size_t); */
65 static int process_arguments (int, char **);
66 void print_help (void);
67 void print_usage (void);
69 #define EXPECT server_expect[0]
70 static char *SERVICE = "TCP";
71 static char *SEND = NULL;
72 static char *QUIT = NULL;
73 static int PROTOCOL = IPPROTO_TCP; /* most common is default */
74 static int PORT = 0;
76 static char timestamp[17] = "";
77 static int server_port = 0;
78 static char *server_address = NULL;
79 static char *server_send = NULL;
80 static char *server_quit = NULL;
81 static char **server_expect;
82 static size_t server_expect_count = 0;
83 static size_t maxbytes = 0;
84 static char **warn_codes = NULL;
85 static size_t warn_codes_count = 0;
86 static char **crit_codes = NULL;
87 static size_t crit_codes_count = 0;
88 static unsigned int delay = 0;
89 static double warning_time = 0;
90 static double critical_time = 0;
91 static double elapsed_time = 0;
92 static long microsec;
93 static int sd = 0;
94 #define MAXBUF 1024
95 static char buffer[MAXBUF];
96 static int expect_mismatch_state = STATE_WARNING;
98 #define FLAG_SSL 0x01
99 #define FLAG_VERBOSE 0x02
100 #define FLAG_EXACT_MATCH 0x04
101 #define FLAG_TIME_WARN 0x08
102 #define FLAG_TIME_CRIT 0x10
103 #define FLAG_HIDE_OUTPUT 0x20
104 static size_t flags = FLAG_EXACT_MATCH;
106 int
107 main (int argc, char **argv)
108 {
109 int result = STATE_UNKNOWN;
110 int i;
111 char *status = NULL;
112 struct timeval tv;
113 size_t len, match = -1;
115 setlocale (LC_ALL, "");
116 bindtextdomain (PACKAGE, LOCALEDIR);
117 textdomain (PACKAGE);
119 /* determine program- and service-name quickly */
120 progname = strrchr(argv[0], '/');
121 if(progname != NULL) progname++;
122 else progname = argv[0];
124 len = strlen(progname);
125 if(len > 6 && !memcmp(progname, "check_", 6)) {
126 SERVICE = progname + 6;
127 for(i = 0; i < len - 6; i++)
128 SERVICE[i] = toupper(SERVICE[i]);
129 }
131 /* set up a resonable buffer at first (will be realloc()'ed if
132 * user specifies other options) */
133 server_expect = calloc(sizeof(char *), 2);
135 /* determine defaults for this service's protocol */
136 if (!strncmp(SERVICE, "UDP", 3)) {
137 PROTOCOL = IPPROTO_UDP;
138 }
139 else if (!strncmp(SERVICE, "FTP", 3)) {
140 EXPECT = "220";
141 QUIT = "QUIT\r\n";
142 PORT = 21;
143 }
144 else if (!strncmp(SERVICE, "POP", 3) || !strncmp(SERVICE, "POP3", 4)) {
145 EXPECT = "+OK";
146 QUIT = "QUIT\r\n";
147 PORT = 110;
148 }
149 else if (!strncmp(SERVICE, "SMTP", 4)) {
150 EXPECT = "220";
151 QUIT = "QUIT\r\n";
152 PORT = 25;
153 }
154 else if (!strncmp(SERVICE, "IMAP", 4)) {
155 EXPECT = "* OK";
156 QUIT = "a1 LOGOUT\r\n";
157 PORT = 143;
158 }
159 #ifdef HAVE_SSL
160 else if (!strncmp(SERVICE, "SIMAP", 5)) {
161 EXPECT = "* OK";
162 QUIT = "a1 LOGOUT\r\n";
163 flags |= FLAG_SSL;
164 PORT = 993;
165 }
166 else if (!strncmp(SERVICE, "SPOP", 4)) {
167 EXPECT = "+OK";
168 QUIT = "QUIT\r\n";
169 flags |= FLAG_SSL;
170 PORT = 995;
171 }
172 else if (!strncmp(SERVICE, "SSMTP", 5)) {
173 EXPECT = "220";
174 QUIT = "QUIT\r\n";
175 flags |= FLAG_SSL;
176 PORT = 465;
177 }
178 else if (!strncmp(SERVICE, "JABBER", 6)) {
179 SEND = "<stream:stream to=\'host\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>\n";
180 EXPECT = "<?xml version=\'1.0\'?><stream:stream xmlns:stream=\'http://etherx.jabber.org/streams\'";
181 QUIT = "</stream:stream>\n";
182 flags |= FLAG_SSL | FLAG_HIDE_OUTPUT;
183 PORT = 5222;
184 }
185 else if (!strncmp (SERVICE, "NNTPS", 5)) {
186 server_expect_count = 2;
187 server_expect[0] = "200";
188 server_expect[1] = "201";
189 QUIT = "QUIT\r\n";
190 flags |= FLAG_SSL;
191 PORT = 563;
192 }
193 #endif
194 else if (!strncmp (SERVICE, "NNTP", 4)) {
195 server_expect_count = 2;
196 server_expect = malloc(sizeof(char *) * server_expect_count);
197 server_expect[0] = strdup("200");
198 server_expect[1] = strdup("201");
199 QUIT = "QUIT\r\n";
200 PORT = 119;
201 }
202 /* fallthrough check, so it's supposed to use reverse matching */
203 else if (strcmp (SERVICE, "TCP"))
204 usage (_("CRITICAL - Generic check_tcp called with unknown service\n"));
206 server_address = "127.0.0.1";
207 server_port = PORT;
208 server_send = SEND;
209 server_quit = QUIT;
210 status = NULL;
212 if (process_arguments (argc, argv) == ERROR)
213 usage4 (_("Could not parse arguments"));
215 if(flags & FLAG_VERBOSE) {
216 printf("Using service %s\n", SERVICE);
217 printf("Port: %d\n", PORT);
218 printf("flags: 0x%x\n", flags);
219 }
221 if(EXPECT && !server_expect_count)
222 server_expect_count++;
224 /* set up the timer */
225 signal (SIGALRM, socket_timeout_alarm_handler);
226 alarm (socket_timeout);
228 /* try to connect to the host at the given port number */
229 gettimeofday (&tv, NULL);
230 #ifdef HAVE_SSL
231 if (flags & FLAG_SSL && check_cert == TRUE) {
232 if (connect_SSL () != OK)
233 die (STATE_CRITICAL,_("CRITICAL - Could not make SSL connection\n"));
234 if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) {
235 result = check_certificate (&server_cert);
236 X509_free(server_cert);
237 }
238 else {
239 printf(_("CRITICAL - Cannot retrieve server certificate.\n"));
240 result = STATE_CRITICAL;
241 }
243 SSL_shutdown (ssl);
244 SSL_free (ssl);
245 SSL_CTX_free (ctx);
246 close (sd);
247 return result;
248 }
249 else if (flags & FLAG_SSL)
250 result = connect_SSL ();
251 else
252 #endif
253 result = np_net_connect (server_address, server_port, &sd, PROTOCOL);
255 if (result == STATE_CRITICAL)
256 return STATE_CRITICAL;
258 if (server_send != NULL) { /* Something to send? */
259 #ifdef HAVE_SSL
260 if (flags & FLAG_SSL)
261 SSL_write(ssl, server_send, (int)strlen(server_send));
262 else
263 #endif
264 send (sd, server_send, strlen(server_send), 0);
265 }
267 if (delay > 0) {
268 tv.tv_sec += delay;
269 sleep (delay);
270 }
272 if(flags & FLAG_VERBOSE) {
273 printf("server_expect_count: %d\n", server_expect_count);
274 for(i = 0; i < server_expect_count; i++)
275 printf("\t%d: %s\n", i, server_expect[i]);
276 }
278 /* if(len) later on, we know we have a non-NULL response */
279 len = 0;
280 if (server_expect_count) {
282 /* watch for the expect string */
283 while ((i = my_recv(buffer, sizeof(buffer))) > 0) {
284 status = realloc(status, len + i + 1);
285 memcpy(&status[len], buffer, i);
286 len += i;
288 /* stop reading if user-forced or data-starved */
289 if(i < sizeof(buffer) || (maxbytes && len >= maxbytes))
290 break;
292 if (maxbytes && len >= maxbytes)
293 break;
294 }
296 /* no data when expected, so return critical */
297 if (len == 0)
298 die (STATE_CRITICAL, _("No data received from host\n"));
300 /* force null-termination and strip whitespace from end of output */
301 status[len--] = '\0';
302 /* print raw output if we're debugging */
303 if(flags & FLAG_VERBOSE)
304 printf("received %d bytes from host\n#-raw-recv-------#\n%s\n#-raw-recv-------#\n",
305 len + 1, status);
306 while(isspace(status[len])) status[len--] = '\0';
308 for (i = 0; i < server_expect_count; i++) {
309 match = -2; /* tag it so we know if we tried and failed */
310 if (flags & FLAG_VERBOSE)
311 printf ("looking for [%s] %s [%s]\n", server_expect[i],
312 (flags & FLAG_EXACT_MATCH) ? "in beginning of" : "anywhere in",
313 status);
315 /* match it. math first in short-circuit */
316 if ((flags & FLAG_EXACT_MATCH && !strncmp(status, server_expect[i], strlen(server_expect[i]))) ||
317 (!(flags & FLAG_EXACT_MATCH) && strstr(status, server_expect[i])))
318 {
319 if(flags & FLAG_VERBOSE) puts("found it");
320 match = i;
321 break;
322 }
323 }
324 }
326 if (server_quit != NULL) {
327 #ifdef HAVE_SSL
328 if (flags & FLAG_SSL) {
329 SSL_write (ssl, server_quit, (int)strlen(server_quit));
330 SSL_shutdown (ssl);
331 SSL_free (ssl);
332 SSL_CTX_free (ctx);
333 }
334 else
335 #endif
336 send (sd, server_quit, strlen (server_quit), 0);
337 }
339 /* close the connection */
340 if (sd)
341 close (sd);
343 microsec = deltime (tv);
344 elapsed_time = (double)microsec / 1.0e6;
346 if (flags & FLAG_TIME_CRIT && elapsed_time > critical_time)
347 result = STATE_CRITICAL;
348 else if (flags & FLAG_TIME_WARN && elapsed_time > warning_time)
349 result = STATE_WARNING;
351 /* did we get the response we hoped? */
352 if(match == -2 && result != STATE_CRITICAL)
353 result = STATE_WARNING;
355 /* reset the alarm */
356 alarm (0);
358 /* this is a bit stupid, because we don't want to print the
359 * response time (which can look ok to the user) if we didn't get
360 * the response we were looking for. if-else */
361 printf(_("%s %s - "), SERVICE, state_text(result));
363 if(match == -2 && len && !(flags & FLAG_HIDE_OUTPUT))
364 printf("Unexpected response from host: %s", status);
365 else
366 printf("%.3f second response time on port %d",
367 elapsed_time, server_port);
369 if (match != -2 && !(flags & FLAG_HIDE_OUTPUT) && len)
370 printf (" [%s]", status);
372 /* perf-data doesn't apply when server doesn't talk properly,
373 * so print all zeroes on warn and crit */
374 if(match == -2)
375 printf ("|time=%fs;0.0;0.0;0.0;0.0", elapsed_time);
376 else
377 printf("|%s",
378 fperfdata ("time", elapsed_time, "s",
379 TRUE, warning_time,
380 TRUE, critical_time,
381 TRUE, 0,
382 TRUE, socket_timeout)
383 );
385 putchar('\n');
386 return result;
387 }
391 /* process command-line arguments */
392 static int
393 process_arguments (int argc, char **argv)
394 {
395 int c;
397 int option = 0;
398 static struct option longopts[] = {
399 {"hostname", required_argument, 0, 'H'},
400 {"critical-time", required_argument, 0, 'c'},
401 {"warning-time", required_argument, 0, 'w'},
402 {"critical-codes", required_argument, 0, 'C'},
403 {"warning-codes", required_argument, 0, 'W'},
404 {"timeout", required_argument, 0, 't'},
405 {"protocol", required_argument, 0, 'P'},
406 {"port", required_argument, 0, 'p'},
407 {"send", required_argument, 0, 's'},
408 {"expect", required_argument, 0, 'e'},
409 {"maxbytes", required_argument, 0, 'm'},
410 {"quit", required_argument, 0, 'q'},
411 {"jail", required_argument, 0, 'j'},
412 {"delay", required_argument, 0, 'd'},
413 {"refuse", required_argument, 0, 'r'},
414 {"mismatch", required_argument, 0, 'M'},
415 {"use-ipv4", no_argument, 0, '4'},
416 {"use-ipv6", no_argument, 0, '6'},
417 {"verbose", no_argument, 0, 'v'},
418 {"version", no_argument, 0, 'V'},
419 {"help", no_argument, 0, 'h'},
420 #ifdef HAVE_SSL
421 {"ssl", no_argument, 0, 'S'},
422 {"certificate", required_argument, 0, 'D'},
423 #endif
424 {0, 0, 0, 0}
425 };
427 if (argc < 2)
428 usage4 (_("No arguments found"));
430 /* backwards compatibility */
431 for (c = 1; c < argc; c++) {
432 if (strcmp ("-to", argv[c]) == 0)
433 strcpy (argv[c], "-t");
434 else if (strcmp ("-wt", argv[c]) == 0)
435 strcpy (argv[c], "-w");
436 else if (strcmp ("-ct", argv[c]) == 0)
437 strcpy (argv[c], "-c");
438 }
440 if (!is_option (argv[1])) {
441 server_address = argv[1];
442 argv[1] = argv[0];
443 argv = &argv[1];
444 argc--;
445 }
447 while (1) {
448 c = getopt_long (argc, argv, "+hVv46H:s:e:q:m:c:w:t:p:C:W:d:Sr:jD:M:",
449 longopts, &option);
451 if (c == -1 || c == EOF || c == 1)
452 break;
454 switch (c) {
455 case '?': /* print short usage statement if args not parsable */
456 usage2 (_("Unknown argument"), optarg);
457 case 'h': /* help */
458 print_help ();
459 exit (STATE_OK);
460 case 'V': /* version */
461 print_revision (progname, revision);
462 exit (STATE_OK);
463 case 'v': /* verbose mode */
464 flags |= FLAG_VERBOSE;
465 break;
466 case '4':
467 address_family = AF_INET;
468 break;
469 case '6':
470 #ifdef USE_IPV6
471 address_family = AF_INET6;
472 #else
473 usage4 (_("IPv6 support not available"));
474 #endif
475 break;
476 case 'H': /* hostname */
477 if (is_host (optarg) == FALSE)
478 usage2 (_("Invalid hostname/address"), optarg);
479 server_address = optarg;
480 break;
481 case 'c': /* critical */
482 if (!is_intnonneg (optarg))
483 usage4 (_("Critical threshold must be a positive integer"));
484 else
485 critical_time = strtod (optarg, NULL);
486 flags |= FLAG_TIME_CRIT;
487 break;
488 case 'j': /* hide output */
489 flags |= FLAG_HIDE_OUTPUT;
490 break;
491 case 'w': /* warning */
492 if (!is_intnonneg (optarg))
493 usage4 (_("Warning threshold must be a positive integer"));
494 else
495 warning_time = strtod (optarg, NULL);
496 flags |= FLAG_TIME_WARN;
497 break;
498 case 'C':
499 crit_codes = realloc (crit_codes, ++crit_codes_count);
500 crit_codes[crit_codes_count - 1] = optarg;
501 break;
502 case 'W':
503 warn_codes = realloc (warn_codes, ++warn_codes_count);
504 warn_codes[warn_codes_count - 1] = optarg;
505 break;
506 case 't': /* timeout */
507 if (!is_intpos (optarg))
508 usage4 (_("Timeout interval must be a positive integer"));
509 else
510 socket_timeout = atoi (optarg);
511 break;
512 case 'p': /* port */
513 if (!is_intpos (optarg))
514 usage4 (_("Port must be a positive integer"));
515 else
516 server_port = atoi (optarg);
517 break;
518 case 's':
519 server_send = optarg;
520 break;
521 case 'e': /* expect string (may be repeated) */
522 EXPECT = NULL;
523 flags &= ~FLAG_EXACT_MATCH;
524 if (server_expect_count == 0)
525 server_expect = malloc (sizeof (char *) * (++server_expect_count));
526 else
527 server_expect = realloc (server_expect, sizeof (char *) * (++server_expect_count));
528 server_expect[server_expect_count - 1] = optarg;
529 break;
530 case 'm':
531 if (!is_intpos (optarg))
532 usage4 (_("Maxbytes must be a positive integer"));
533 else
534 maxbytes = strtol (optarg, NULL, 0);
535 case 'q':
536 asprintf(&server_quit, "%s\r\n", optarg);
537 break;
538 case 'r':
539 if (!strncmp(optarg,"ok",2))
540 econn_refuse_state = STATE_OK;
541 else if (!strncmp(optarg,"warn",4))
542 econn_refuse_state = STATE_WARNING;
543 else if (!strncmp(optarg,"crit",4))
544 econn_refuse_state = STATE_CRITICAL;
545 else
546 usage4 (_("Refuse must be one of ok, warn, crit"));
547 break;
548 case 'M':
549 if (!strncmp(optarg,"ok",2))
550 expect_mismatch_state = STATE_OK;
551 else if (!strncmp(optarg,"warn",4))
552 expect_mismatch_state = STATE_WARNING;
553 else if (!strncmp(optarg,"crit",4))
554 expect_mismatch_state = STATE_CRITICAL;
555 else
556 usage4 (_("Mismatch must be one of ok, warn, crit"));
557 break;
558 case 'd':
559 if (is_intpos (optarg))
560 delay = atoi (optarg);
561 else
562 usage4 (_("Delay must be a positive integer"));
563 break;
564 case 'D': /* Check SSL cert validity - days 'til certificate expiration */
565 #ifdef HAVE_SSL
566 if (!is_intnonneg (optarg))
567 usage2 (_("Invalid certificate expiration period"), optarg);
568 days_till_exp = atoi (optarg);
569 check_cert = TRUE;
570 flags |= FLAG_SSL;
571 break;
572 #endif
573 /* fallthrough if we don't have ssl */
574 case 'S':
575 #ifdef HAVE_SSL
576 flags |= FLAG_SSL;
577 #else
578 die (STATE_UNKNOWN, _("Invalid option - SSL is not available"));
579 #endif
580 break;
581 }
582 }
584 if (server_address == NULL)
585 usage4 (_("You must provide a server address"));
587 return TRUE;
588 }
591 /* SSL-specific functions */
592 #ifdef HAVE_SSL
593 static int
594 connect_SSL (void)
595 {
596 SSL_METHOD *meth;
598 /* Initialize SSL context */
599 SSLeay_add_ssl_algorithms ();
600 meth = SSLv23_client_method ();
601 SSL_load_error_strings ();
602 OpenSSL_add_all_algorithms();
603 if ((ctx = SSL_CTX_new (meth)) == NULL)
604 {
605 printf (_("CRITICAL - Cannot create SSL context.\n"));
606 return STATE_CRITICAL;
607 }
609 /* Initialize alarm signal handling */
610 signal (SIGALRM, socket_timeout_alarm_handler);
612 /* Set socket timeout */
613 alarm (socket_timeout);
615 /* Save start time */
616 time (&start_time);
618 /* Make TCP connection */
619 if (my_tcp_connect (server_address, server_port, &sd) == STATE_OK && was_refused == FALSE)
620 {
621 /* Do the SSL handshake */
622 if ((ssl = SSL_new (ctx)) != NULL)
623 {
624 SSL_set_fd (ssl, sd);
625 if (SSL_connect(ssl) == 1)
626 return OK;
627 /* ERR_print_errors_fp (stderr); */
628 printf (_("CRITICAL - Cannot make SSL connection "));
629 ERR_print_errors_fp (stdout);
630 /* printf("\n"); */
631 }
632 else
633 {
634 printf (_("CRITICAL - Cannot initiate SSL handshake.\n"));
635 }
636 SSL_free (ssl);
637 }
639 SSL_CTX_free (ctx);
640 close (sd);
642 return STATE_CRITICAL;
643 }
645 static int
646 check_certificate (X509 ** certificate)
647 {
648 ASN1_STRING *tm;
649 int offset;
650 struct tm stamp;
651 int days_left;
654 /* Retrieve timestamp of certificate */
655 tm = X509_get_notAfter (*certificate);
657 /* Generate tm structure to process timestamp */
658 if (tm->type == V_ASN1_UTCTIME) {
659 if (tm->length < 10) {
660 printf (_("CRITICAL - Wrong time format in certificate.\n"));
661 return STATE_CRITICAL;
662 }
663 else {
664 stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0');
665 if (stamp.tm_year < 50)
666 stamp.tm_year += 100;
667 offset = 0;
668 }
669 }
670 else {
671 if (tm->length < 12) {
672 printf (_("CRITICAL - Wrong time format in certificate.\n"));
673 return STATE_CRITICAL;
674 }
675 else {
676 stamp.tm_year =
677 (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 +
678 (tm->data[2] - '0') * 10 + (tm->data[3] - '0');
679 stamp.tm_year -= 1900;
680 offset = 2;
681 }
682 }
683 stamp.tm_mon =
684 (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1;
685 stamp.tm_mday =
686 (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0');
687 stamp.tm_hour =
688 (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0');
689 stamp.tm_min =
690 (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0');
691 stamp.tm_sec = 0;
692 stamp.tm_isdst = -1;
694 days_left = (mktime (&stamp) - time (NULL)) / 86400;
695 snprintf
696 (timestamp, 16, "%02d/%02d/%04d %02d:%02d",
697 stamp.tm_mon + 1,
698 stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min);
700 if (days_left > 0 && days_left <= days_till_exp) {
701 printf (_("Certificate expires in %d day(s) (%s).\n"), days_left, timestamp);
702 return STATE_WARNING;
703 }
704 if (days_left < 0) {
705 printf (_("Certificate expired on %s.\n"), timestamp);
706 return STATE_CRITICAL;
707 }
709 if (days_left == 0) {
710 printf (_("Certificate expires today (%s).\n"), timestamp);
711 return STATE_WARNING;
712 }
714 printf (_("Certificate will expire on %s.\n"), timestamp);
716 return STATE_OK;
717 }
718 #endif /* HAVE_SSL */
721 void
722 print_help (void)
723 {
724 print_revision (progname, revision);
726 printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
727 printf (COPYRIGHT, copyright, email);
729 printf (_("This plugin tests %s connections with the specified host.\n\n"),
730 SERVICE);
732 print_usage ();
734 printf (_(UT_HELP_VRSN));
736 printf (_(UT_HOST_PORT), 'p', "none");
738 printf (_(UT_IPv46));
740 printf (_("\
741 -s, --send=STRING\n\
742 String to send to the server\n\
743 -e, --expect=STRING\n\
744 String to expect in server response\n\
745 -q, --quit=STRING\n\
746 String to send server to initiate a clean close of the connection\n"));
748 printf (_("\
749 -r, --refuse=ok|warn|crit\n\
750 Accept tcp refusals with states ok, warn, crit (default: crit)\n\
751 -M, --mismatch=ok|warn|crit\n\
752 Accept expected string mismatches with states ok, warn, crit (default: warn)\n\
753 -j, --jail\n\
754 Hide output from TCP socket\n\
755 -m, --maxbytes=INTEGER\n\
756 Close connection once more than this number of bytes are received\n\
757 -d, --delay=INTEGER\n\
758 Seconds to wait between sending string and polling for response\n"));
760 #ifdef HAVE_SSL
761 printf (_("\
762 -D, --certificate=INTEGER\n\
763 Minimum number of days a certificate has to be valid.\n\
764 -S, --ssl\n\
765 Use SSL for the connection.\n"));
766 #endif
768 printf (_(UT_WARN_CRIT));
770 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
772 printf (_(UT_VERBOSE));
774 printf (_(UT_SUPPORT));
775 }
778 void
779 print_usage (void)
780 {
781 printf ("\
782 Usage: %s -H host -p port [-w <warning time>] [-c <critical time>]\n\
783 [-s <send string>] [-e <expect string>] [-q <quit string>]\n\
784 [-m <maximum bytes>] [-d <delay>] [-t <timeout seconds>]\n\
785 [-r <refuse state>] [-M <mismatch state>] [-v] [-4|-6] [-j]\n\
786 [-D <days to cert expiry>] [-S <use SSL>]\n", progname);
787 }