summaryrefslogtreecommitdiffstats
path: root/plugins/check_smtp.c
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2023-08-29 14:59:11 (GMT)
committerGitHub <noreply@github.com>2023-08-29 14:59:11 (GMT)
commit554c1433cf624cd0ed0565e4a8d06ea5e4bdf942 (patch)
tree8581b8ea800314cd2c5565c0a8d276a7bf97533b /plugins/check_smtp.c
parent29613c3be27fb9c7f97ca87e3da3712977e419dc (diff)
parentdc3598662eb5efe2f71e87391da6d2f8ca17be1e (diff)
downloadmonitoring-plugins-554c1433cf624cd0ed0565e4a8d06ea5e4bdf942.tar.gz
Merge pull request #1889 from franzs/feature_check_smtp_ssl
Add support for SMTP over TLS
Diffstat (limited to 'plugins/check_smtp.c')
-rw-r--r--plugins/check_smtp.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index 996bd87..fc0ae2c 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -42,15 +42,16 @@ 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};
55#define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n" 56#define PROXY_PREFIX "PROXY TCP4 0.0.0.0 0.0.0.0 25 25\r\n"
56#define SMTP_EXPECT "220" 57#define SMTP_EXPECT "220"
@@ -83,6 +84,7 @@ int eflags = 0;
83int errcode, excode; 84int errcode, excode;
84 85
85int server_port = SMTP_PORT; 86int server_port = SMTP_PORT;
87int server_port_option = 0;
86char *server_address = NULL; 88char *server_address = NULL;
87char *server_expect = NULL; 89char *server_expect = NULL;
88char *mail_command = NULL; 90char *mail_command = NULL;
@@ -103,6 +105,7 @@ double critical_time = 0;
103int check_critical_time = FALSE; 105int check_critical_time = FALSE;
104int verbose = 0; 106int verbose = 0;
105int use_ssl = FALSE; 107int use_ssl = FALSE;
108int use_starttls = FALSE;
106int use_sni = FALSE; 109int use_sni = FALSE;
107short use_proxy_prefix = FALSE; 110short use_proxy_prefix = FALSE;
108short use_ehlo = FALSE; 111short use_ehlo = FALSE;
@@ -186,14 +189,27 @@ main (int argc, char **argv)
186 result = my_tcp_connect (server_address, server_port, &sd); 189 result = my_tcp_connect (server_address, server_port, &sd);
187 190
188 if (result == STATE_OK) { /* we connected */ 191 if (result == STATE_OK) { /* we connected */
189
190 /* If requested, send PROXY header */ 192 /* If requested, send PROXY header */
191 if (use_proxy_prefix) { 193 if (use_proxy_prefix) {
192 if (verbose) 194 if (verbose)
193 printf ("Sending header %s\n", PROXY_PREFIX); 195 printf ("Sending header %s\n", PROXY_PREFIX);
194 send(sd, PROXY_PREFIX, strlen(PROXY_PREFIX), 0); 196 my_send(PROXY_PREFIX, strlen(PROXY_PREFIX));
195 } 197 }
196 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
212
197 /* watch for the SMTP connection string and */ 213 /* watch for the SMTP connection string and */
198 /* return a WARNING status if we couldn't read any data */ 214 /* return a WARNING status if we couldn't read any data */
199 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { 215 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
@@ -205,7 +221,7 @@ main (int argc, char **argv)
205 xasprintf(&server_response, "%s", buffer); 221 xasprintf(&server_response, "%s", buffer);
206 222
207 /* send the HELO/EHLO command */ 223 /* send the HELO/EHLO command */
208 send(sd, helocmd, strlen(helocmd), 0); 224 my_send(helocmd, strlen(helocmd));
209 225
210 /* allow for response to helo command to reach us */ 226 /* allow for response to helo command to reach us */
211 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { 227 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
@@ -218,14 +234,14 @@ main (int argc, char **argv)
218 } 234 }
219 } 235 }
220 236
221 if(use_ssl && ! supports_tls){ 237 if(use_starttls && ! supports_tls){
222 printf(_("WARNING - TLS not supported by server\n")); 238 printf(_("WARNING - TLS not supported by server\n"));
223 smtp_quit(); 239 smtp_quit();
224 return STATE_WARNING; 240 return STATE_WARNING;
225 } 241 }
226 242
227#ifdef HAVE_SSL 243#ifdef HAVE_SSL
228 if(use_ssl) { 244 if(use_starttls) {
229 /* send the STARTTLS command */ 245 /* send the STARTTLS command */
230 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); 246 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
231 247
@@ -489,6 +505,8 @@ process_arguments (int argc, char **argv)
489 {"use-ipv6", no_argument, 0, '6'}, 505 {"use-ipv6", no_argument, 0, '6'},
490 {"help", no_argument, 0, 'h'}, 506 {"help", no_argument, 0, 'h'},
491 {"lmtp", no_argument, 0, 'L'}, 507 {"lmtp", no_argument, 0, 'L'},
508 {"ssl", no_argument, 0, 's'},
509 {"tls", no_argument, 0, 's'},
492 {"starttls",no_argument,0,'S'}, 510 {"starttls",no_argument,0,'S'},
493 {"sni", no_argument, 0, SNI_OPTION}, 511 {"sni", no_argument, 0, SNI_OPTION},
494 {"certificate",required_argument,0,'D'}, 512 {"certificate",required_argument,0,'D'},
@@ -510,7 +528,7 @@ process_arguments (int argc, char **argv)
510 } 528 }
511 529
512 while (1) { 530 while (1) {
513 c = getopt_long (argc, argv, "+hVv46Lrt: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",
514 longopts, &option); 532 longopts, &option);
515 533
516 if (c == -1 || c == EOF) 534 if (c == -1 || c == EOF)
@@ -527,7 +545,7 @@ process_arguments (int argc, char **argv)
527 break; 545 break;
528 case 'p': /* port */ 546 case 'p': /* port */
529 if (is_intpos (optarg)) 547 if (is_intpos (optarg))
530 server_port = atoi (optarg); 548 server_port_option = atoi (optarg);
531 else 549 else
532 usage4 (_("Port must be a positive integer")); 550 usage4 (_("Port must be a positive integer"));
533 break; 551 break;
@@ -632,10 +650,14 @@ process_arguments (int argc, char **argv)
632#else 650#else
633 usage (_("SSL support not available - install OpenSSL and recompile")); 651 usage (_("SSL support not available - install OpenSSL and recompile"));
634#endif 652#endif
635 // fall through 653 case 's':
654 /* ssl */
655 use_ssl = TRUE;
656 server_port = SMTPS_PORT;
657 break;
636 case 'S': 658 case 'S':
637 /* starttls */ 659 /* starttls */
638 use_ssl = TRUE; 660 use_starttls = TRUE;
639 use_ehlo = TRUE; 661 use_ehlo = TRUE;
640 break; 662 break;
641 case SNI_OPTION: 663 case SNI_OPTION:
@@ -694,6 +716,14 @@ process_arguments (int argc, char **argv)
694 if (from_arg==NULL) 716 if (from_arg==NULL)
695 from_arg = strdup(" "); 717 from_arg = strdup(" ");
696 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
697 return validate_arguments (); 727 return validate_arguments ();
698} 728}
699 729
@@ -851,6 +881,9 @@ print_help (void)
851#ifdef HAVE_SSL 881#ifdef HAVE_SSL
852 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); 882 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
853 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);
854 printf (" %s\n", "-S, --starttls"); 887 printf (" %s\n", "-S, --starttls");
855 printf (" %s\n", _("Use STARTTLS for the connection.")); 888 printf (" %s\n", _("Use STARTTLS for the connection."));
856 printf (" %s\n", "--sni"); 889 printf (" %s\n", "--sni");