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.c172
1 files changed, 164 insertions, 8 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index ad85c7f6..e99f0675 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -45,6 +45,7 @@ enum {
45#define SMTP_EHLO "EHLO " 45#define SMTP_EHLO "EHLO "
46#define SMTP_QUIT "QUIT\r\n" 46#define SMTP_QUIT "QUIT\r\n"
47#define SMTP_STARTTLS "STARTTLS\r\n" 47#define SMTP_STARTTLS "STARTTLS\r\n"
48#define SMTP_AUTH_LOGIN "AUTH LOGIN\r\n"
48 49
49#ifndef HOST_MAX_BYTES 50#ifndef HOST_MAX_BYTES
50#define HOST_MAX_BYTES 255 51#define HOST_MAX_BYTES 255
@@ -82,6 +83,9 @@ int nresponses=0;
82int response_size=0; 83int response_size=0;
83char **commands = NULL; 84char **commands = NULL;
84char **responses = NULL; 85char **responses = NULL;
86char *authtype = NULL;
87char *authuser = NULL;
88char *authpass = NULL;
85int warning_time = 0; 89int warning_time = 0;
86int check_warning_time = FALSE; 90int check_warning_time = FALSE;
87int critical_time = 0; 91int critical_time = 0;
@@ -99,6 +103,47 @@ enum {
99 MAXBUF = 1024 103 MAXBUF = 1024
100}; 104};
101 105
106/* written by lauri alanko */
107static char *
108base64 (const char *bin, size_t len)
109{
110
111 char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1);
112 size_t i = 0, j = 0;
113
114 char BASE64_END = '=';
115 char base64_table[64];
116 strncpy (base64_table, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 64);
117
118 while (j < len - 2) {
119 buf[i++] = base64_table[bin[j] >> 2];
120 buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)];
121 buf[i++] = base64_table[((bin[j + 1] & 15) << 2) | (bin[j + 2] >> 6)];
122 buf[i++] = base64_table[bin[j + 2] & 63];
123 j += 3;
124 }
125
126 switch (len - j) {
127 case 1:
128 buf[i++] = base64_table[bin[j] >> 2];
129 buf[i++] = base64_table[(bin[j] & 3) << 4];
130 buf[i++] = BASE64_END;
131 buf[i++] = BASE64_END;
132 break;
133 case 2:
134 buf[i++] = base64_table[bin[j] >> 2];
135 buf[i++] = base64_table[((bin[j] & 3) << 4) | (bin[j + 1] >> 4)];
136 buf[i++] = base64_table[(bin[j + 1] & 15) << 2];
137 buf[i++] = BASE64_END;
138 break;
139 case 0:
140 break;
141 }
142
143 buf[i] = '\0';
144 return buf;
145}
146
102int 147int
103main (int argc, char **argv) 148main (int argc, char **argv)
104{ 149{
@@ -109,6 +154,7 @@ main (int argc, char **argv)
109 int result = STATE_UNKNOWN; 154 int result = STATE_UNKNOWN;
110 char *cmd_str = NULL; 155 char *cmd_str = NULL;
111 char *helocmd = NULL; 156 char *helocmd = NULL;
157 char *error_msg = NULL;
112 struct timeval tv; 158 struct timeval tv;
113 struct hostent *hp; 159 struct hostent *hp;
114 160
@@ -293,6 +339,92 @@ main (int argc, char **argv)
293 n++; 339 n++;
294 } 340 }
295 341
342 if (authtype != NULL) {
343 if (strcmp (authtype, "LOGIN") == 0) {
344 char *abuf;
345 int ret;
346 do {
347 if (authuser == NULL) {
348 result = STATE_CRITICAL;
349 error_msg = _("no authuser specified, ");
350 break;
351 }
352 if (authpass == NULL) {
353 result = STATE_CRITICAL;
354 error_msg = _("no authpass specified, ");
355 break;
356 }
357
358 /* send AUTH LOGIN */
359 my_send(SMTP_AUTH_LOGIN, strlen(SMTP_AUTH_LOGIN));
360 if (verbose)
361 printf (_("sent %s\n"), "AUTH LOGIN");
362
363 if((ret = my_recv(buffer, MAXBUF - 1)) < 0){
364 error_msg = _("recv() failed after AUTH LOGIN, \n");
365 result = STATE_WARNING;
366 break;
367 }
368 buffer[ret] = 0;
369 if (verbose)
370 printf (_("received %s\n"), buffer);
371
372 if (strncmp (buffer, "334", 3) != 0) {
373 result = STATE_CRITICAL;
374 error_msg = _("invalid response received after AUTH LOGIN, ");
375 break;
376 }
377
378 /* encode authuser with base64 */
379 abuf = base64 (authuser, strlen(authuser));
380 strcat (abuf, "\r\n");
381 my_send(abuf, strlen(abuf));
382 if (verbose)
383 printf (_("sent %s\n"), abuf);
384
385 if ((ret = my_recv(buffer, MAX_INPUT_BUFFER-1)) == -1) {
386 result = STATE_CRITICAL;
387 error_msg = _("recv() failed after sending authuser, ");
388 break;
389 }
390 buffer[ret] = 0;
391 if (verbose) {
392 printf (_("received %s\n"), buffer);
393 }
394 if (strncmp (buffer, "334", 3) != 0) {
395 result = STATE_CRITICAL;
396 error_msg = _("invalid response received after authuser, ");
397 break;
398 }
399 /* encode authpass with base64 */
400 abuf = base64 (authpass, strlen(authpass));
401 strcat (abuf, "\r\n");
402 my_send(abuf, strlen(abuf));
403 if (verbose) {
404 printf (_("sent %s\n"), abuf);
405 }
406 if ((ret = my_recv(buffer, MAX_INPUT_BUFFER-1)) == -1) {
407 result = STATE_CRITICAL;
408 error_msg = _("recv() failed after sending authpass, ");
409 break;
410 }
411 buffer[ret] = 0;
412 if (verbose) {
413 printf (_("received %s\n"), buffer);
414 }
415 if (strncmp (buffer, "235", 3) != 0) {
416 result = STATE_CRITICAL;
417 error_msg = _("invalid response received after authpass, ");
418 break;
419 }
420 break;
421 } while (0);
422 } else {
423 result = STATE_CRITICAL;
424 error_msg = _("only authtype LOGIN is supported, ");
425 }
426 }
427
296 /* tell the server we're done */ 428 /* tell the server we're done */
297 my_send (SMTP_QUIT, strlen (SMTP_QUIT)); 429 my_send (SMTP_QUIT, strlen (SMTP_QUIT));
298 430
@@ -313,13 +445,15 @@ main (int argc, char **argv)
313 result = STATE_WARNING; 445 result = STATE_WARNING;
314 } 446 }
315 447
316 printf (_("SMTP %s - %.3f sec. response time%s%s|%s\n"), 448 printf (_("SMTP %s - %s%.3f sec. response time%s%s|%s\n"),
317 state_text (result), elapsed_time, 449 state_text (result),
318 verbose?", ":"", verbose?buffer:"", 450 (error_msg == NULL ? "" : error_msg),
319 fperfdata ("time", elapsed_time, "s", 451 elapsed_time,
320 (int)check_warning_time, warning_time, 452 verbose?", ":"", verbose?buffer:"",
321 (int)check_critical_time, critical_time, 453 fperfdata ("time", elapsed_time, "s",
322 TRUE, 0, FALSE, 0)); 454 (int)check_warning_time, warning_time,
455 (int)check_critical_time, critical_time,
456 TRUE, 0, FALSE, 0));
323 457
324 return result; 458 return result;
325} 459}
@@ -342,6 +476,9 @@ process_arguments (int argc, char **argv)
342 {"port", required_argument, 0, 'p'}, 476 {"port", required_argument, 0, 'p'},
343 {"from", required_argument, 0, 'f'}, 477 {"from", required_argument, 0, 'f'},
344 {"fqdn", required_argument, 0, 'F'}, 478 {"fqdn", required_argument, 0, 'F'},
479 {"authtype", required_argument, 0, 'A'},
480 {"authuser", required_argument, 0, 'U'},
481 {"authpass", required_argument, 0, 'P'},
345 {"command", required_argument, 0, 'C'}, 482 {"command", required_argument, 0, 'C'},
346 {"response", required_argument, 0, 'R'}, 483 {"response", required_argument, 0, 'R'},
347 {"nocommand", required_argument, 0, 'n'}, 484 {"nocommand", required_argument, 0, 'n'},
@@ -368,7 +505,7 @@ process_arguments (int argc, char **argv)
368 } 505 }
369 506
370 while (1) { 507 while (1) {
371 c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:F:", 508 c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:F:A:U:P:",
372 longopts, &option); 509 longopts, &option);
373 510
374 if (c == -1 || c == EOF) 511 if (c == -1 || c == EOF)
@@ -397,6 +534,15 @@ process_arguments (int argc, char **argv)
397 from_arg = optarg; 534 from_arg = optarg;
398 smtp_use_dummycmd = 1; 535 smtp_use_dummycmd = 1;
399 break; 536 break;
537 case 'A':
538 authtype = optarg;
539 break;
540 case 'U':
541 authuser = optarg;
542 break;
543 case 'P':
544 authpass = optarg;
545 break;
400 case 'e': /* server expect string on 220 */ 546 case 'e': /* server expect string on 220 */
401 server_expect = optarg; 547 server_expect = optarg;
402 break; 548 break;
@@ -562,6 +708,15 @@ print_help (void)
562 Use STARTTLS for the connection.\n")); 708 Use STARTTLS for the connection.\n"));
563#endif 709#endif
564 710
711 printf("\
712 -A, --authtype=STRING\n\
713 SMTP AUTH type to check (default none, only LOGIN supported)\n\
714 -U, --authuser=STRING\n\
715 SMTP AUTH username\n\
716 -P, --authpass=STRING\n\
717 SMTP AUTH password\n\
718 ");
719
565 printf (_(UT_WARN_CRIT)); 720 printf (_(UT_WARN_CRIT));
566 721
567 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT); 722 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
@@ -584,6 +739,7 @@ print_usage (void)
584{ 739{
585 printf ("\ 740 printf ("\
586Usage: %s -H host [-p port] [-e expect] [-C command] [-f from addr]\n\ 741Usage: %s -H host [-p port] [-e expect] [-C command] [-f from addr]\n\
742 [-A authtype -U authuser -P authpass]\n\
587 [-w warn] [-c crit] [-t timeout] [-S] [-D days] [-n] [-v] [-4|-6]\n", progname); 743 [-w warn] [-c crit] [-t timeout] [-S] [-D days] [-n] [-v] [-4|-6]\n", progname);
588} 744}
589 745