diff options
Diffstat (limited to 'plugins/check_smtp.c')
-rw-r--r-- | plugins/check_smtp.c | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index 494bc2c..a861a71 100644 --- a/plugins/check_smtp.c +++ b/plugins/check_smtp.c | |||
@@ -41,7 +41,7 @@ const char *email = "nagiosplug-devel@lists.sourceforge.net"; | |||
41 | 41 | ||
42 | #ifdef HAVE_SSL | 42 | #ifdef HAVE_SSL |
43 | int check_cert = FALSE; | 43 | int check_cert = FALSE; |
44 | int days_till_exp; | 44 | int days_till_exp_warn, days_till_exp_crit; |
45 | # define my_recv(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) | 45 | # define my_recv(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_read(buf, len) : read(sd, buf, len)) |
46 | # define my_send(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) | 46 | # define my_send(buf, len) ((use_ssl && ssl_established) ? np_net_ssl_write(buf, len) : send(sd, buf, len, 0)) |
47 | #else /* ifndef HAVE_SSL */ | 47 | #else /* ifndef HAVE_SSL */ |
@@ -87,9 +87,9 @@ int errcode, excode; | |||
87 | int server_port = SMTP_PORT; | 87 | int server_port = SMTP_PORT; |
88 | char *server_address = NULL; | 88 | char *server_address = NULL; |
89 | char *server_expect = NULL; | 89 | char *server_expect = NULL; |
90 | int smtp_use_dummycmd = 0; | ||
91 | char *mail_command = NULL; | 90 | char *mail_command = NULL; |
92 | char *from_arg = NULL; | 91 | char *from_arg = NULL; |
92 | int send_mail_from=0; | ||
93 | int ncommands=0; | 93 | int ncommands=0; |
94 | int command_size=0; | 94 | int command_size=0; |
95 | int nresponses=0; | 95 | int nresponses=0; |
@@ -156,17 +156,17 @@ main (int argc, char **argv) | |||
156 | } | 156 | } |
157 | } | 157 | } |
158 | if(use_ehlo) | 158 | if(use_ehlo) |
159 | asprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); | 159 | xasprintf (&helocmd, "%s%s%s", SMTP_EHLO, localhostname, "\r\n"); |
160 | else | 160 | else |
161 | asprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); | 161 | xasprintf (&helocmd, "%s%s%s", SMTP_HELO, localhostname, "\r\n"); |
162 | 162 | ||
163 | if (verbose) | 163 | if (verbose) |
164 | printf("HELOCMD: %s", helocmd); | 164 | printf("HELOCMD: %s", helocmd); |
165 | 165 | ||
166 | /* initialize the MAIL command with optional FROM command */ | 166 | /* initialize the MAIL command with optional FROM command */ |
167 | asprintf (&cmd_str, "%sFROM: %s%s", mail_command, from_arg, "\r\n"); | 167 | xasprintf (&cmd_str, "%sFROM:<%s>%s", mail_command, from_arg, "\r\n"); |
168 | 168 | ||
169 | if (verbose && smtp_use_dummycmd) | 169 | if (verbose && send_mail_from) |
170 | printf ("FROM CMD: %s", cmd_str); | 170 | printf ("FROM CMD: %s", cmd_str); |
171 | 171 | ||
172 | /* initialize alarm signal handling */ | 172 | /* initialize alarm signal handling */ |
@@ -275,7 +275,7 @@ main (int argc, char **argv) | |||
275 | 275 | ||
276 | # ifdef USE_OPENSSL | 276 | # ifdef USE_OPENSSL |
277 | if ( check_cert ) { | 277 | if ( check_cert ) { |
278 | result = np_net_ssl_check_cert(days_till_exp); | 278 | result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); |
279 | my_close(); | 279 | my_close(); |
280 | return result; | 280 | return result; |
281 | } | 281 | } |
@@ -283,23 +283,14 @@ main (int argc, char **argv) | |||
283 | } | 283 | } |
284 | #endif | 284 | #endif |
285 | 285 | ||
286 | /* sendmail will syslog a "NOQUEUE" error if session does not attempt | 286 | if (send_mail_from) { |
287 | * to do something useful. This can be prevented by giving a command | ||
288 | * even if syntax is illegal (MAIL requires a FROM:<...> argument) | ||
289 | * | ||
290 | * According to rfc821 you can include a null reversepath in the from command | ||
291 | * - but a log message is generated on the smtp server. | ||
292 | * | ||
293 | * Use the -f option to provide a FROM address | ||
294 | */ | ||
295 | if (smtp_use_dummycmd) { | ||
296 | my_send(cmd_str, strlen(cmd_str)); | 287 | my_send(cmd_str, strlen(cmd_str)); |
297 | if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) | 288 | if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) |
298 | printf("%s", buffer); | 289 | printf("%s", buffer); |
299 | } | 290 | } |
300 | 291 | ||
301 | while (n < ncommands) { | 292 | while (n < ncommands) { |
302 | asprintf (&cmd_str, "%s%s", commands[n], "\r\n"); | 293 | xasprintf (&cmd_str, "%s%s", commands[n], "\r\n"); |
303 | my_send(cmd_str, strlen(cmd_str)); | 294 | my_send(cmd_str, strlen(cmd_str)); |
304 | if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) | 295 | if (recvlines(buffer, MAX_INPUT_BUFFER) >= 1 && verbose) |
305 | printf("%s", buffer); | 296 | printf("%s", buffer); |
@@ -336,12 +327,12 @@ main (int argc, char **argv) | |||
336 | do { | 327 | do { |
337 | if (authuser == NULL) { | 328 | if (authuser == NULL) { |
338 | result = STATE_CRITICAL; | 329 | result = STATE_CRITICAL; |
339 | asprintf(&error_msg, _("no authuser specified, ")); | 330 | xasprintf(&error_msg, _("no authuser specified, ")); |
340 | break; | 331 | break; |
341 | } | 332 | } |
342 | if (authpass == NULL) { | 333 | if (authpass == NULL) { |
343 | result = STATE_CRITICAL; | 334 | result = STATE_CRITICAL; |
344 | asprintf(&error_msg, _("no authpass specified, ")); | 335 | xasprintf(&error_msg, _("no authpass specified, ")); |
345 | break; | 336 | break; |
346 | } | 337 | } |
347 | 338 | ||
@@ -351,7 +342,7 @@ main (int argc, char **argv) | |||
351 | printf (_("sent %s\n"), "AUTH LOGIN"); | 342 | printf (_("sent %s\n"), "AUTH LOGIN"); |
352 | 343 | ||
353 | if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { | 344 | if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { |
354 | asprintf(&error_msg, _("recv() failed after AUTH LOGIN, ")); | 345 | xasprintf(&error_msg, _("recv() failed after AUTH LOGIN, ")); |
355 | result = STATE_WARNING; | 346 | result = STATE_WARNING; |
356 | break; | 347 | break; |
357 | } | 348 | } |
@@ -360,21 +351,20 @@ main (int argc, char **argv) | |||
360 | 351 | ||
361 | if (strncmp (buffer, "334", 3) != 0) { | 352 | if (strncmp (buffer, "334", 3) != 0) { |
362 | result = STATE_CRITICAL; | 353 | result = STATE_CRITICAL; |
363 | asprintf(&error_msg, _("invalid response received after AUTH LOGIN, ")); | 354 | xasprintf(&error_msg, _("invalid response received after AUTH LOGIN, ")); |
364 | break; | 355 | break; |
365 | } | 356 | } |
366 | 357 | ||
367 | /* encode authuser with base64 */ | 358 | /* encode authuser with base64 */ |
368 | base64_encode_alloc (authuser, strlen(authuser), &abuf); | 359 | base64_encode_alloc (authuser, strlen(authuser), &abuf); |
369 | /* FIXME: abuf shouldn't have enough space to strcat a '\r\n' into it. */ | 360 | xasprintf(&abuf, "%s\r\n", abuf); |
370 | strcat (abuf, "\r\n"); | ||
371 | my_send(abuf, strlen(abuf)); | 361 | my_send(abuf, strlen(abuf)); |
372 | if (verbose) | 362 | if (verbose) |
373 | printf (_("sent %s\n"), abuf); | 363 | printf (_("sent %s\n"), abuf); |
374 | 364 | ||
375 | if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { | 365 | if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { |
376 | result = STATE_CRITICAL; | 366 | result = STATE_CRITICAL; |
377 | asprintf(&error_msg, _("recv() failed after sending authuser, ")); | 367 | xasprintf(&error_msg, _("recv() failed after sending authuser, ")); |
378 | break; | 368 | break; |
379 | } | 369 | } |
380 | if (verbose) { | 370 | if (verbose) { |
@@ -382,20 +372,19 @@ main (int argc, char **argv) | |||
382 | } | 372 | } |
383 | if (strncmp (buffer, "334", 3) != 0) { | 373 | if (strncmp (buffer, "334", 3) != 0) { |
384 | result = STATE_CRITICAL; | 374 | result = STATE_CRITICAL; |
385 | asprintf(&error_msg, _("invalid response received after authuser, ")); | 375 | xasprintf(&error_msg, _("invalid response received after authuser, ")); |
386 | break; | 376 | break; |
387 | } | 377 | } |
388 | /* encode authpass with base64 */ | 378 | /* encode authpass with base64 */ |
389 | base64_encode_alloc (authpass, strlen(authpass), &abuf); | 379 | base64_encode_alloc (authpass, strlen(authpass), &abuf); |
390 | /* FIXME: abuf shouldn't have enough space to strcat a '\r\n' into it. */ | 380 | xasprintf(&abuf, "%s\r\n", abuf); |
391 | strcat (abuf, "\r\n"); | ||
392 | my_send(abuf, strlen(abuf)); | 381 | my_send(abuf, strlen(abuf)); |
393 | if (verbose) { | 382 | if (verbose) { |
394 | printf (_("sent %s\n"), abuf); | 383 | printf (_("sent %s\n"), abuf); |
395 | } | 384 | } |
396 | if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { | 385 | if ((ret = recvlines(buffer, MAX_INPUT_BUFFER)) <= 0) { |
397 | result = STATE_CRITICAL; | 386 | result = STATE_CRITICAL; |
398 | asprintf(&error_msg, _("recv() failed after sending authpass, ")); | 387 | xasprintf(&error_msg, _("recv() failed after sending authpass, ")); |
399 | break; | 388 | break; |
400 | } | 389 | } |
401 | if (verbose) { | 390 | if (verbose) { |
@@ -403,14 +392,14 @@ main (int argc, char **argv) | |||
403 | } | 392 | } |
404 | if (strncmp (buffer, "235", 3) != 0) { | 393 | if (strncmp (buffer, "235", 3) != 0) { |
405 | result = STATE_CRITICAL; | 394 | result = STATE_CRITICAL; |
406 | asprintf(&error_msg, _("invalid response received after authpass, ")); | 395 | xasprintf(&error_msg, _("invalid response received after authpass, ")); |
407 | break; | 396 | break; |
408 | } | 397 | } |
409 | break; | 398 | break; |
410 | } while (0); | 399 | } while (0); |
411 | } else { | 400 | } else { |
412 | result = STATE_CRITICAL; | 401 | result = STATE_CRITICAL; |
413 | asprintf(&error_msg, _("only authtype LOGIN is supported, ")); | 402 | xasprintf(&error_msg, _("only authtype LOGIN is supported, ")); |
414 | } | 403 | } |
415 | } | 404 | } |
416 | 405 | ||
@@ -454,6 +443,7 @@ int | |||
454 | process_arguments (int argc, char **argv) | 443 | process_arguments (int argc, char **argv) |
455 | { | 444 | { |
456 | int c; | 445 | int c; |
446 | char* temp; | ||
457 | 447 | ||
458 | int option = 0; | 448 | int option = 0; |
459 | static struct option longopts[] = { | 449 | static struct option longopts[] = { |
@@ -520,8 +510,9 @@ process_arguments (int argc, char **argv) | |||
520 | localhostname = strdup(optarg); | 510 | localhostname = strdup(optarg); |
521 | break; | 511 | break; |
522 | case 'f': /* from argument */ | 512 | case 'f': /* from argument */ |
523 | from_arg = optarg; | 513 | from_arg = optarg + strspn(optarg, "<"); |
524 | smtp_use_dummycmd = 1; | 514 | from_arg = strndup(from_arg, strcspn(from_arg, ">")); |
515 | send_mail_from = 1; | ||
525 | break; | 516 | break; |
526 | case 'A': | 517 | case 'A': |
527 | authtype = optarg; | 518 | authtype = optarg; |
@@ -600,12 +591,26 @@ process_arguments (int argc, char **argv) | |||
600 | case 'D': | 591 | case 'D': |
601 | /* Check SSL cert validity */ | 592 | /* Check SSL cert validity */ |
602 | #ifdef USE_OPENSSL | 593 | #ifdef USE_OPENSSL |
603 | if (!is_intnonneg (optarg)) | 594 | if ((temp=strchr(optarg,','))!=NULL) { |
604 | usage2 ("Invalid certificate expiration period",optarg); | 595 | *temp='\0'; |
605 | days_till_exp = atoi (optarg); | 596 | if (!is_intnonneg (temp)) |
606 | check_cert = TRUE; | 597 | usage2 ("Invalid certificate expiration period", optarg); |
598 | days_till_exp_warn = atoi(optarg); | ||
599 | *temp=','; | ||
600 | temp++; | ||
601 | if (!is_intnonneg (temp)) | ||
602 | usage2 (_("Invalid certificate expiration period"), temp); | ||
603 | days_till_exp_crit = atoi (temp); | ||
604 | } | ||
605 | else { | ||
606 | days_till_exp_crit=0; | ||
607 | if (!is_intnonneg (optarg)) | ||
608 | usage2 ("Invalid certificate expiration period", optarg); | ||
609 | days_till_exp_warn = atoi (optarg); | ||
610 | } | ||
611 | check_cert = TRUE; | ||
607 | #else | 612 | #else |
608 | usage (_("SSL support not available - install OpenSSL and recompile")); | 613 | usage (_("SSL support not available - install OpenSSL and recompile")); |
609 | #endif | 614 | #endif |
610 | break; | 615 | break; |
611 | case '4': | 616 | case '4': |
@@ -638,7 +643,7 @@ process_arguments (int argc, char **argv) | |||
638 | usage2 (_("Invalid hostname/address"), argv[c]); | 643 | usage2 (_("Invalid hostname/address"), argv[c]); |
639 | } | 644 | } |
640 | else { | 645 | else { |
641 | asprintf (&server_address, "127.0.0.1"); | 646 | xasprintf (&server_address, "127.0.0.1"); |
642 | } | 647 | } |
643 | } | 648 | } |
644 | 649 | ||
@@ -771,7 +776,7 @@ void | |||
771 | print_help (void) | 776 | print_help (void) |
772 | { | 777 | { |
773 | char *myport; | 778 | char *myport; |
774 | asprintf (&myport, "%d", SMTP_PORT); | 779 | xasprintf (&myport, "%d", SMTP_PORT); |
775 | 780 | ||
776 | print_revision (progname, NP_VERSION); | 781 | print_revision (progname, NP_VERSION); |
777 | 782 | ||
@@ -795,14 +800,14 @@ print_help (void) | |||
795 | printf (_(" String to expect in first line of server response (default: '%s')\n"), SMTP_EXPECT); | 800 | printf (_(" String to expect in first line of server response (default: '%s')\n"), SMTP_EXPECT); |
796 | printf (" %s\n", "-C, --command=STRING"); | 801 | printf (" %s\n", "-C, --command=STRING"); |
797 | printf (" %s\n", _("SMTP command (may be used repeatedly)")); | 802 | printf (" %s\n", _("SMTP command (may be used repeatedly)")); |
798 | printf (" %s\n", "-R, --command=STRING"); | 803 | printf (" %s\n", "-R, --response=STRING"); |
799 | printf (" %s\n", _("Expected response to command (may be used repeatedly)")); | 804 | printf (" %s\n", _("Expected response to command (may be used repeatedly)")); |
800 | printf (" %s\n", "-f, --from=STRING"); | 805 | printf (" %s\n", "-f, --from=STRING"); |
801 | printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), | 806 | printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), |
802 | printf (" %s\n", "-F, --fqdn=STRING"); | 807 | printf (" %s\n", "-F, --fqdn=STRING"); |
803 | printf (" %s\n", _("FQDN used for HELO")); | 808 | printf (" %s\n", _("FQDN used for HELO")); |
804 | #ifdef HAVE_SSL | 809 | #ifdef HAVE_SSL |
805 | printf (" %s\n", "-D, --certificate=INTEGER"); | 810 | printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); |
806 | printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); | 811 | printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); |
807 | printf (" %s\n", "-S, --starttls"); | 812 | printf (" %s\n", "-S, --starttls"); |
808 | printf (" %s\n", _("Use STARTTLS for the connection.")); | 813 | printf (" %s\n", _("Use STARTTLS for the connection.")); |
@@ -838,8 +843,8 @@ void | |||
838 | print_usage (void) | 843 | print_usage (void) |
839 | { | 844 | { |
840 | printf ("%s\n", _("Usage:")); | 845 | printf ("%s\n", _("Usage:")); |
841 | printf ("%s -H host [-p port] [-e expect] [-C command] [-f from addr]", progname); | 846 | printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); |
842 | printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout]\n"); | 847 | printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); |
843 | printf ("[-F fqdn] [-S] [-D days] [-v] [-4|-6] [-q]\n"); | 848 | printf ("[-F fqdn] [-S] [-D warn days cert expire[,crit days cert expire]] [-v] \n"); |
844 | } | 849 | } |
845 | 850 | ||