summaryrefslogtreecommitdiffstats
path: root/plugins/check_smtp.c
diff options
context:
space:
mode:
authorFranz Schwartau <franz@electromail.org>2023-08-21 14:53:48 (GMT)
committerFranz Schwartau <franz@electromail.org>2023-08-29 07:46:50 (GMT)
commitead5526efa4f713e8001baed409067b0474cb72d (patch)
tree57061b7dfff076b8d432fd1d492308d5f38ee6b8 /plugins/check_smtp.c
parent29613c3be27fb9c7f97ca87e3da3712977e419dc (diff)
downloadmonitoring-plugins-ead5526efa4f713e8001baed409067b0474cb72d.tar.gz
Add support for SMTP over TLS
This is commonly used on smtps (465) port. PROXY protocol is not implemented with TLS in check_smtp.c, yet. Backported from nagios-plugins: https://github.com/nagios-plugins/nagios-plugins/commit/0a8cf08ebb0740aa55d6c60d3b79fcab282604fb
Diffstat (limited to 'plugins/check_smtp.c')
-rw-r--r--plugins/check_smtp.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index 996bd87..f3ba9e3 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -42,8 +42,8 @@ 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)
@@ -103,6 +103,7 @@ double critical_time = 0;
103int check_critical_time = FALSE; 103int check_critical_time = FALSE;
104int verbose = 0; 104int verbose = 0;
105int use_ssl = FALSE; 105int use_ssl = FALSE;
106int use_starttls = FALSE;
106int use_sni = FALSE; 107int use_sni = FALSE;
107short use_proxy_prefix = FALSE; 108short use_proxy_prefix = FALSE;
108short use_ehlo = FALSE; 109short use_ehlo = FALSE;
@@ -186,12 +187,25 @@ main (int argc, char **argv)
186 result = my_tcp_connect (server_address, server_port, &sd); 187 result = my_tcp_connect (server_address, server_port, &sd);
187 188
188 if (result == STATE_OK) { /* we connected */ 189 if (result == STATE_OK) { /* we connected */
190#ifdef HAVE_SSL
191 if (use_ssl) {
192 result = np_net_ssl_init_with_hostname(sd, (use_sni ? server_address : NULL));
193 if (result != STATE_OK) {
194 printf (_("CRITICAL - Cannot create SSL context.\n"));
195 close(sd);
196 np_net_ssl_cleanup();
197 return STATE_CRITICAL;
198 } else {
199 ssl_established = 1;
200 }
201 }
202#endif
189 203
190 /* If requested, send PROXY header */ 204 /* If requested, send PROXY header */
191 if (use_proxy_prefix) { 205 if (use_proxy_prefix) {
192 if (verbose) 206 if (verbose)
193 printf ("Sending header %s\n", PROXY_PREFIX); 207 printf ("Sending header %s\n", PROXY_PREFIX);
194 send(sd, PROXY_PREFIX, strlen(PROXY_PREFIX), 0); 208 my_send(PROXY_PREFIX, strlen(PROXY_PREFIX));
195 } 209 }
196 210
197 /* watch for the SMTP connection string and */ 211 /* watch for the SMTP connection string and */
@@ -205,7 +219,7 @@ main (int argc, char **argv)
205 xasprintf(&server_response, "%s", buffer); 219 xasprintf(&server_response, "%s", buffer);
206 220
207 /* send the HELO/EHLO command */ 221 /* send the HELO/EHLO command */
208 send(sd, helocmd, strlen(helocmd), 0); 222 my_send(helocmd, strlen(helocmd));
209 223
210 /* allow for response to helo command to reach us */ 224 /* allow for response to helo command to reach us */
211 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) { 225 if (recvlines(buffer, MAX_INPUT_BUFFER) <= 0) {
@@ -218,14 +232,14 @@ main (int argc, char **argv)
218 } 232 }
219 } 233 }
220 234
221 if(use_ssl && ! supports_tls){ 235 if(use_starttls && ! supports_tls){
222 printf(_("WARNING - TLS not supported by server\n")); 236 printf(_("WARNING - TLS not supported by server\n"));
223 smtp_quit(); 237 smtp_quit();
224 return STATE_WARNING; 238 return STATE_WARNING;
225 } 239 }
226 240
227#ifdef HAVE_SSL 241#ifdef HAVE_SSL
228 if(use_ssl) { 242 if(use_starttls) {
229 /* send the STARTTLS command */ 243 /* send the STARTTLS command */
230 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0); 244 send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
231 245
@@ -489,6 +503,7 @@ process_arguments (int argc, char **argv)
489 {"use-ipv6", no_argument, 0, '6'}, 503 {"use-ipv6", no_argument, 0, '6'},
490 {"help", no_argument, 0, 'h'}, 504 {"help", no_argument, 0, 'h'},
491 {"lmtp", no_argument, 0, 'L'}, 505 {"lmtp", no_argument, 0, 'L'},
506 {"ssl", no_argument, 0, 's'},
492 {"starttls",no_argument,0,'S'}, 507 {"starttls",no_argument,0,'S'},
493 {"sni", no_argument, 0, SNI_OPTION}, 508 {"sni", no_argument, 0, SNI_OPTION},
494 {"certificate",required_argument,0,'D'}, 509 {"certificate",required_argument,0,'D'},
@@ -510,7 +525,7 @@ process_arguments (int argc, char **argv)
510 } 525 }
511 526
512 while (1) { 527 while (1) {
513 c = getopt_long (argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:SD:F:A:U:P:q", 528 c = getopt_long (argc, argv, "+hVv46Lrt:p:f:e:c:w:H:C:R:sSD:F:A:U:P:q",
514 longopts, &option); 529 longopts, &option);
515 530
516 if (c == -1 || c == EOF) 531 if (c == -1 || c == EOF)
@@ -632,10 +647,13 @@ process_arguments (int argc, char **argv)
632#else 647#else
633 usage (_("SSL support not available - install OpenSSL and recompile")); 648 usage (_("SSL support not available - install OpenSSL and recompile"));
634#endif 649#endif
635 // fall through 650 case 's':
651 /* ssl */
652 use_ssl = TRUE;
653 break;
636 case 'S': 654 case 'S':
637 /* starttls */ 655 /* starttls */
638 use_ssl = TRUE; 656 use_starttls = TRUE;
639 use_ehlo = TRUE; 657 use_ehlo = TRUE;
640 break; 658 break;
641 case SNI_OPTION: 659 case SNI_OPTION:
@@ -694,6 +712,14 @@ process_arguments (int argc, char **argv)
694 if (from_arg==NULL) 712 if (from_arg==NULL)
695 from_arg = strdup(" "); 713 from_arg = strdup(" ");
696 714
715 if (use_starttls && use_ssl) {
716 usage4 (_("Set either -s/--ssl or -S/--starttls"));
717 }
718
719 if (use_ssl && use_proxy_prefix) {
720 usage4 (_("PROXY protocol (-r/--proxy) is not implemented with SSL/TLS (-s/--ssl), yet."));
721 }
722
697 return validate_arguments (); 723 return validate_arguments ();
698} 724}
699 725
@@ -851,6 +877,8 @@ print_help (void)
851#ifdef HAVE_SSL 877#ifdef HAVE_SSL
852 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]"); 878 printf (" %s\n", "-D, --certificate=INTEGER[,INTEGER]");
853 printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); 879 printf (" %s\n", _("Minimum number of days a certificate has to be valid."));
880 printf (" %s\n", "-s, --ssl");
881 printf (" %s\n", _("Use SSL/TLS for the connection."));
854 printf (" %s\n", "-S, --starttls"); 882 printf (" %s\n", "-S, --starttls");
855 printf (" %s\n", _("Use STARTTLS for the connection.")); 883 printf (" %s\n", _("Use STARTTLS for the connection."));
856 printf (" %s\n", "--sni"); 884 printf (" %s\n", "--sni");