diff options
Diffstat (limited to 'plugins/check_smtp.c')
-rw-r--r-- | plugins/check_smtp.c | 172 |
1 files changed, 164 insertions, 8 deletions
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c index ad85c7f..e99f067 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; | |||
82 | int response_size=0; | 83 | int response_size=0; |
83 | char **commands = NULL; | 84 | char **commands = NULL; |
84 | char **responses = NULL; | 85 | char **responses = NULL; |
86 | char *authtype = NULL; | ||
87 | char *authuser = NULL; | ||
88 | char *authpass = NULL; | ||
85 | int warning_time = 0; | 89 | int warning_time = 0; |
86 | int check_warning_time = FALSE; | 90 | int check_warning_time = FALSE; |
87 | int critical_time = 0; | 91 | int critical_time = 0; |
@@ -99,6 +103,47 @@ enum { | |||
99 | MAXBUF = 1024 | 103 | MAXBUF = 1024 |
100 | }; | 104 | }; |
101 | 105 | ||
106 | /* written by lauri alanko */ | ||
107 | static char * | ||
108 | base64 (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 | |||
102 | int | 147 | int |
103 | main (int argc, char **argv) | 148 | main (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 ("\ |
586 | Usage: %s -H host [-p port] [-e expect] [-C command] [-f from addr]\n\ | 741 | Usage: %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 | ||