summaryrefslogtreecommitdiffstats
path: root/plugins/check_smtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_smtp.c')
-rw-r--r--plugins/check_smtp.c90
1 files changed, 77 insertions, 13 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index c1e92dff..fc0ae2c4 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -3,7 +3,7 @@
3* Monitoring check_smtp plugin 3* Monitoring check_smtp plugin
4* 4*
5* License: GPL 5* License: GPL
6* Copyright (c) 2000-2007 Monitoring Plugins Development Team 6* Copyright (c) 2000-2023 Monitoring Plugins Development Team
7* 7*
8* Description: 8* Description:
9* 9*
@@ -42,16 +42,18 @@ const char *email = "devel@monitoring-plugins.org";
42#ifdef HAVE_SSL 42#ifdef HAVE_SSL
43int check_cert = FALSE; 43int check_cert = FALSE;
44int days_till_exp_warn, days_till_exp_crit; 44int 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_starttls || 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_starttls || 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 */
48# define my_recv(buf, len) read(sd, buf, len) 48# define my_recv(buf, len) read(sd, buf, len)
49# define my_send(buf, len) send(sd, buf, len, 0) 49# define my_send(buf, len) send(sd, buf, len, 0)
50#endif 50#endif
51 51
52enum { 52enum {
53 SMTP_PORT = 25 53 SMTP_PORT = 25,
54 SMTPS_PORT = 465
54}; 55};
56#define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n"
55#define SMTP_EXPECT "220" 57#define SMTP_EXPECT "220"
56#define SMTP_HELO "HELO " 58#define SMTP_HELO "HELO "
57#define SMTP_EHLO "EHLO " 59#define SMTP_EHLO "EHLO "
@@ -82,6 +84,7 @@ int eflags = 0;
82int errcode, excode; 84int errcode, excode;
83 85
84int server_port = SMTP_PORT; 86int server_port = SMTP_PORT;
87int server_port_option = 0;
85char *server_address = NULL; 88char *server_address = NULL;
86char *server_expect = NULL; 89char *server_expect = NULL;
87char *mail_command = NULL; 90char *mail_command = NULL;
@@ -102,6 +105,9 @@ double critical_time = 0;
102int check_critical_time = FALSE; 105int check_critical_time = FALSE;
103int verbose = 0; 106int verbose = 0;
104int use_ssl = FALSE; 107int use_ssl = FALSE;
108int use_starttls = FALSE;
109int use_sni = FALSE;
110short use_proxy_prefix = FALSE;
105short use_ehlo = FALSE; 111short use_ehlo = FALSE;
106short use_lhlo = FALSE; 112short use_lhlo = FALSE;
107short ssl_established = 0; 113short ssl_established = 0;
@@ -183,6 +189,26 @@ main (int argc, char **argv)
183 result = my_tcp_connect (server_address, server_port, &sd); 189 result = my_tcp_connect (server_address, server_port, &sd);
184 190
185 if (result == STATE_OK) { /* we connected */ 191 if (result == STATE_OK) { /* we connected */
192 /* If requested, send PROXY header */
193 if (use_proxy_prefix) {
194 if (verbose)
195 printf ("Sending header %s\n", PROXY_PREFIX);
196 my_send(PROXY_PREFIX, strlen(PROXY_PREFIX));
197 }
198
199#ifdef HAVE_SSL
200 if (use_ssl) {
201 result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL));
202 if (result != STATE_OK) {
203 printf (_("CRITICAL - Cannot create SSL context.\n"));
204 close(sd);
205 np_net_ssl_cleanup();
206 return STATE_CRITICAL;
207 } else {
208 ssl_established = 1;
209 }
210 }
211#endif
186 212
187 /* watch for the SMTP connection string and */ 213 /* watch for the SMTP connection string and */
188 /* return a WARNING status if we couldn't read any data */ 214 /* return a WARNING status if we couldn't read any data */
@@ -195,7 +221,7 @@ main (int argc, char **argv)
195 xasprintf(&server_response, "%s", buffer); 221 xasprintf(&server_response, "%s", buffer);
196 222
197 /* send the HELO/EHLO command */ 223 /* send the HELO/EHLO command */
198 send(sd, helocmd, strlen(helocmd), 0); 224 my_send(helocmd, strlen(helocmd));
199 225
200 /* allow for response to helo command to reach us */ 226 /* allow for response to helo command to reach us */
201 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { 227 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
@@ -208,14 +234,14 @@ main (int argc, char **argv)
208 } 234 }
209 } 235 }
210 236
211 if(use_ssl && ! supports_tls){ 237 if(use_starttls && ! supports_tls){
212 printf(_("WARNING - TLS not supported by server\n")); 238 printf(_("WARNING - TLS not supported by server\n"));
213 smtp_quit(); 239 smtp_quit();
214 return STATE_WARNING; 240 return STATE_WARNING;
215 } 241 }
216 242
217#ifdef HAVE_SSL 243#ifdef HAVE_SSL
218 if(use_ssl) { 244 if(use_starttls) {
219 /* send the STARTTLS command */ 245 /* send the STARTTLS command */
220 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); 246 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
221 247
@@ -225,7 +251,7 @@ main (int argc, char **argv)
225 smtp_quit(); 251 smtp_quit();
226 return STATE_UNKNOWN; 252 return STATE_UNKNOWN;
227 } 253 }
228 result = np_net_ssl_init(sd); 254 result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL));
229 if(result != STATE_OK) { 255 if(result != STATE_OK) {
230 printf (_("CRITICAL - Cannot create SSL context.\n")); 256 printf (_("CRITICAL - Cannot create SSL context.\n"));
231 close(sd); 257 close(sd);
@@ -454,6 +480,10 @@ process_arguments (int argc, char **argv)
454 int c; 480 int c;
455 char* temp; 481 char* temp;
456 482
483 enum {
484 SNI_OPTION
485 };
486
457 int option = 0; 487 int option = 0;
458 static struct option longopts[] = { 488 static struct option longopts[] = {
459 {"hostname", required_argument, 0, 'H'}, 489 {"hostname", required_argument, 0, 'H'},
@@ -475,9 +505,13 @@ process_arguments (int argc, char **argv)
475 {"use-ipv6", no_argument, 0, '6'}, 505 {"use-ipv6", no_argument, 0, '6'},
476 {"help", no_argument, 0, 'h'}, 506 {"help", no_argument, 0, 'h'},
477 {"lmtp", no_argument, 0, 'L'}, 507 {"lmtp", no_argument, 0, 'L'},
508 {"ssl", no_argument, 0, 's'},
509 {"tls", no_argument, 0, 's'},
478 {"starttls",no_argument,0,'S'}, 510 {"starttls",no_argument,0,'S'},
511 {"sni", no_argument, 0, SNI_OPTION},
479 {"certificate",required_argument,0,'D'}, 512 {"certificate",required_argument,0,'D'},
480 {"ignore-quit-failure",no_argument,0,'q'}, 513 {"ignore-quit-failure",no_argument,0,'q'},
514 {"proxy",no_argument,0,'r'},
481 {0, 0, 0, 0} 515 {0, 0, 0, 0}
482 }; 516 };
483 517
@@ -494,7 +528,7 @@ process_arguments (int argc, char **argv)
494 } 528 }
495 529
496 while (1) { 530 while (1) {
497 c = getopt_long (argc, argv, "+hVv46Lt:p:f:e:c:w:H:C:R:SD:F:A:U:P:q", 531 c = getopt_long (argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q",
498 longopts, &option); 532 longopts, &option);
499 533
500 if (c == -1 || c == EOF) 534 if (c == -1 || c == EOF)
@@ -511,7 +545,7 @@ process_arguments (int argc, char **argv)
511 break; 545 break;
512 case 'p': /* port */ 546 case 'p': /* port */
513 if (is_intpos (optarg)) 547 if (is_intpos (optarg))
514 server_port = atoi (optarg); 548 server_port_option = atoi (optarg);
515 else 549 else
516 usage4 (_("Port must be a positive integer")); 550 usage4 (_("Port must be a positive integer"));
517 break; 551 break;
@@ -616,11 +650,26 @@ process_arguments (int argc, char **argv)
616#else 650#else
617 usage (_("SSL support not available - install OpenSSL and recompile")); 651 usage (_("SSL support not available - install OpenSSL and recompile"));
618#endif 652#endif
653 case 's':
654 /* ssl */
655 use_ssl = TRUE;
656 server_port = SMTPS_PORT;
657 break;
619 case 'S': 658 case 'S':
620 /* starttls */ 659 /* starttls */
621 use_ssl = TRUE; 660 use_starttls = TRUE;
622 use_ehlo = TRUE; 661 use_ehlo = TRUE;
623 break; 662 break;
663 case SNI_OPTION:
664#ifdef HAVE_SSL
665 use_sni = TRUE;
666#else
667 usage (_("SSL support not available - install OpenSSL and recompile"));
668#endif
669 break;
670 case 'r':
671 use_proxy_prefix = TRUE;
672 break;
624 case 'L': 673 case 'L':
625 use_lhlo = TRUE; 674 use_lhlo = TRUE;
626 break; 675 break;
@@ -667,6 +716,14 @@ process_arguments (int argc, char **argv)
667 if (from_arg==NULL) 716 if (from_arg==NULL)
668 from_arg = strdup(" "); 717 from_arg = strdup(" ");
669 718
719 if (use_starttls && use_ssl) {
720 usage4 (_("Set either -s/--ssl/--tls or -S/--starttls"));
721 }
722
723 if (server_port_option != 0) {
724 server_port = server_port_option;
725 }
726
670 return validate_arguments (); 727 return validate_arguments ();
671} 728}
672 729
@@ -819,11 +876,18 @@ print_help (void)
819 printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")), 876 printf (" %s\n", _("FROM-address to include in MAIL command, required by Exchange 2000")),
820 printf (" %s\n", "-F, --fqdn=STRING"); 877 printf (" %s\n", "-F, --fqdn=STRING");
821 printf (" %s\n", _("FQDN used for HELO")); 878 printf (" %s\n", _("FQDN used for HELO"));
879 printf (" %s\n", "-r, --proxy");
880 printf (" %s\n", _("Use PROXY protocol prefix for the connection."));
822#ifdef HAVE_SSL 881#ifdef HAVE_SSL
823 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); 882 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
824 printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); 883 printf (" %s\n", _("Minimum number of days a certificate has to be valid."));
884 printf (" %s\n", "-s, --ssl, --tls");
885 printf (" %s\n", _("Use SSL/TLS for the connection."));
886 printf (_(" Sets default port to %d.\n"), SMTPS_PORT);
825 printf (" %s\n", "-S, --starttls"); 887 printf (" %s\n", "-S, --starttls");
826 printf (" %s\n", _("Use STARTTLS for the connection.")); 888 printf (" %s\n", _("Use STARTTLS for the connection."));
889 printf (" %s\n", "--sni");
890 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
827#endif 891#endif
828 892
829 printf (" %s\n", "-A, --authtype=STRING"); 893 printf (" %s\n", "-A, --authtype=STRING");
@@ -844,7 +908,7 @@ print_help (void)
844 printf (UT_VERBOSE); 908 printf (UT_VERBOSE);
845 909
846 printf("\n"); 910 printf("\n");
847 printf ("%s\n", _("Successul connects return STATE_OK, refusals and timeouts return")); 911 printf ("%s\n", _("Successful connects return STATE_OK, refusals and timeouts return"));
848 printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful")); 912 printf ("%s\n", _("STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful"));
849 printf ("%s\n", _("connects, but incorrect response messages from the host result in")); 913 printf ("%s\n", _("connects, but incorrect response messages from the host result in"));
850 printf ("%s\n", _("STATE_WARNING return values.")); 914 printf ("%s\n", _("STATE_WARNING return values."));
@@ -860,6 +924,6 @@ print_usage (void)
860 printf ("%s\n", _("Usage:")); 924 printf ("%s\n", _("Usage:"));
861 printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname); 925 printf ("%s -H host [-p port] [-4|-6] [-e expect] [-C command] [-R response] [-f from addr]\n", progname);
862 printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n"); 926 printf ("[-A authtype -U authuser -P authpass] [-w warn] [-c crit] [-t timeout] [-q]\n");
863 printf ("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-v] \n"); 927 printf ("[-F fqdn] [-S] [-L] [-D warn days cert expire[,crit days cert expire]] [-r] [--sni] [-v] \n");
864} 928}
865 929