check_smtp.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /******************************************************************************
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13. $Id$
  14. ******************************************************************************/
  15. const char *progname = "check_smtp";
  16. const char *revision = "$Revision$";
  17. const char *copyright = "2000-2004";
  18. const char *email = "nagiosplug-devel@lists.sourceforge.net";
  19. #include "common.h"
  20. #include "netutils.h"
  21. #include "utils.h"
  22. #ifdef HAVE_SSL_H
  23. # include <rsa.h>
  24. # include <crypto.h>
  25. # include <x509.h>
  26. # include <pem.h>
  27. # include <ssl.h>
  28. # include <err.h>
  29. #else
  30. # ifdef HAVE_OPENSSL_SSL_H
  31. # include <openssl/rsa.h>
  32. # include <openssl/crypto.h>
  33. # include <openssl/x509.h>
  34. # include <openssl/pem.h>
  35. # include <openssl/ssl.h>
  36. # include <openssl/err.h>
  37. # endif
  38. #endif
  39. #ifdef HAVE_SSL
  40. int check_cert = FALSE;
  41. int days_till_exp;
  42. SSL_CTX *ctx;
  43. SSL *ssl;
  44. X509 *server_cert;
  45. int connect_STARTTLS (void);
  46. int check_certificate (X509 **);
  47. #endif
  48. enum {
  49. SMTP_PORT = 25
  50. };
  51. const char *SMTP_EXPECT = "220";
  52. const char *SMTP_HELO = "HELO ";
  53. const char *SMTP_QUIT = "QUIT\r\n";
  54. const char *SMTP_STARTTLS = "STARTTLS\r\n";
  55. int process_arguments (int, char **);
  56. int validate_arguments (void);
  57. void print_help (void);
  58. void print_usage (void);
  59. int myrecv(void);
  60. int my_close(void);
  61. #ifdef HAVE_REGEX_H
  62. #include <regex.h>
  63. char regex_expect[MAX_INPUT_BUFFER] = "";
  64. regex_t preg;
  65. regmatch_t pmatch[10];
  66. char timestamp[10] = "";
  67. char errbuf[MAX_INPUT_BUFFER];
  68. int cflags = REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
  69. int eflags = 0;
  70. int errcode, excode;
  71. #endif
  72. int server_port = SMTP_PORT;
  73. char *server_address = NULL;
  74. char *server_expect = NULL;
  75. int smtp_use_dummycmd = 0;
  76. char *mail_command = NULL;
  77. char *from_arg = NULL;
  78. int ncommands=0;
  79. int command_size=0;
  80. int nresponses=0;
  81. int response_size=0;
  82. char **commands = NULL;
  83. char **responses = NULL;
  84. int warning_time = 0;
  85. int check_warning_time = FALSE;
  86. int critical_time = 0;
  87. int check_critical_time = FALSE;
  88. int verbose = 0;
  89. int use_ssl = FALSE;
  90. int sd;
  91. char buffer[MAX_INPUT_BUFFER];
  92. enum {
  93. TCP_PROTOCOL = 1,
  94. UDP_PROTOCOL = 2,
  95. MAXBUF = 1024
  96. };
  97. int
  98. main (int argc, char **argv)
  99. {
  100. int n = 0;
  101. double elapsed_time;
  102. long microsec;
  103. int result = STATE_UNKNOWN;
  104. char *cmd_str = NULL;
  105. char *helocmd = NULL;
  106. struct timeval tv;
  107. setlocale (LC_ALL, "");
  108. bindtextdomain (PACKAGE, LOCALEDIR);
  109. textdomain (PACKAGE);
  110. if (process_arguments (argc, argv) == ERROR)
  111. usage4 (_("Could not parse arguments"));
  112. /* initialize the HELO command with the localhostname */
  113. #ifndef HOST_MAX_BYTES
  114. #define HOST_MAX_BYTES 255
  115. #endif
  116. helocmd = malloc (HOST_MAX_BYTES);
  117. gethostname(helocmd, HOST_MAX_BYTES);
  118. asprintf (&helocmd, "%s%s%s", SMTP_HELO, helocmd, "\r\n");
  119. /* initialize the MAIL command with optional FROM command */
  120. asprintf (&cmd_str, "%sFROM: %s%s", mail_command, from_arg, "\r\n");
  121. if (verbose && smtp_use_dummycmd)
  122. printf ("FROM CMD: %s", cmd_str);
  123. /* initialize alarm signal handling */
  124. (void) signal (SIGALRM, socket_timeout_alarm_handler);
  125. /* set socket timeout */
  126. (void) alarm (socket_timeout);
  127. /* start timer */
  128. gettimeofday (&tv, NULL);
  129. /* try to connect to the host at the given port number */
  130. result = my_tcp_connect (server_address, server_port, &sd);
  131. if (result == STATE_OK) { /* we connected */
  132. /* watch for the SMTP connection string and */
  133. /* return a WARNING status if we couldn't read any data */
  134. if (recv (sd, buffer, MAX_INPUT_BUFFER - 1, 0) == -1) {
  135. printf (_("recv() failed\n"));
  136. result = STATE_WARNING;
  137. }
  138. else {
  139. if (verbose)
  140. printf ("%s", buffer);
  141. /* strip the buffer of carriage returns */
  142. strip (buffer);
  143. /* make sure we find the response we are looking for */
  144. if (!strstr (buffer, server_expect)) {
  145. if (server_port == SMTP_PORT)
  146. printf (_("Invalid SMTP response received from host\n"));
  147. else
  148. printf (_("Invalid SMTP response received from host on port %d\n"),
  149. server_port);
  150. result = STATE_WARNING;
  151. }
  152. }
  153. #ifdef HAVE_SSL
  154. if(use_ssl) {
  155. /* send the STARTTLS command */
  156. send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
  157. recv(sd,buffer, MAX_INPUT_BUFFER-1, 0); /* wait for it */
  158. if (!strstr (buffer, server_expect)) {
  159. printf (_("Server does not support STARTTLS\n"));
  160. return STATE_UNKNOWN;
  161. }
  162. if(connect_STARTTLS() != OK) {
  163. printf (_("CRITICAL - Cannot create SSL context.\n"));
  164. return STATE_CRITICAL;
  165. }
  166. if ( check_cert ) {
  167. if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) {
  168. result = check_certificate (&server_cert);
  169. X509_free(server_cert);
  170. }
  171. else {
  172. printf (_("CRITICAL - Cannot retrieve server certificate.\n"));
  173. result = STATE_CRITICAL;
  174. }
  175. my_close();
  176. return result;
  177. }
  178. }
  179. #endif
  180. /* send the HELO command */
  181. #ifdef HAVE_SSL
  182. if (use_ssl)
  183. SSL_write(ssl, helocmd, strlen(helocmd));
  184. else
  185. #endif
  186. send(sd, helocmd, strlen(helocmd), 0);
  187. /* allow for response to helo command to reach us */
  188. myrecv();
  189. /* sendmail will syslog a "NOQUEUE" error if session does not attempt
  190. * to do something useful. This can be prevented by giving a command
  191. * even if syntax is illegal (MAIL requires a FROM:<...> argument)
  192. *
  193. * According to rfc821 you can include a null reversepath in the from command
  194. * - but a log message is generated on the smtp server.
  195. *
  196. * You can disable sending mail_command with '--nocommand'
  197. * Use the -f option to provide a FROM address
  198. */
  199. if (smtp_use_dummycmd) {
  200. #ifdef HAVE_SSL
  201. if (use_ssl)
  202. SSL_write(ssl, cmd_str, strlen(cmd_str));
  203. else
  204. #endif
  205. send(sd, cmd_str, strlen(cmd_str), 0);
  206. myrecv();
  207. if (verbose)
  208. printf("%s", buffer);
  209. }
  210. while (n < ncommands) {
  211. asprintf (&cmd_str, "%s%s", commands[n], "\r\n");
  212. #ifdef HAVE_SSL
  213. if (use_ssl)
  214. SSL_write(ssl,cmd_str, strlen(cmd_str));
  215. else
  216. #endif
  217. send(sd, cmd_str, strlen(cmd_str), 0);
  218. myrecv();
  219. if (verbose)
  220. printf("%s", buffer);
  221. strip (buffer);
  222. if (n < nresponses) {
  223. #ifdef HAVE_REGEX_H
  224. cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
  225. errcode = regcomp (&preg, responses[n], cflags);
  226. if (errcode != 0) {
  227. regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
  228. printf (_("Could Not Compile Regular Expression"));
  229. return ERROR;
  230. }
  231. excode = regexec (&preg, buffer, 10, pmatch, eflags);
  232. if (excode == 0) {
  233. result = STATE_OK;
  234. }
  235. else if (excode == REG_NOMATCH) {
  236. result = STATE_WARNING;
  237. printf (_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text (result), buffer, commands[n]);
  238. }
  239. else {
  240. regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER);
  241. printf (_("Execute Error: %s\n"), errbuf);
  242. result = STATE_UNKNOWN;
  243. }
  244. #else
  245. if (strstr(buffer, responses[n])!=buffer) {
  246. result = STATE_WARNING;
  247. printf (_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text (result), buffer, commands[n]);
  248. }
  249. #endif
  250. }
  251. n++;
  252. }
  253. /* tell the server we're done */
  254. #ifdef HAVE_SSL
  255. if (use_ssl)
  256. SSL_write(ssl,SMTP_QUIT, strlen (SMTP_QUIT));
  257. else
  258. #endif
  259. send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0);
  260. /* finally close the connection */
  261. close (sd);
  262. }
  263. /* reset the alarm */
  264. alarm (0);
  265. microsec = deltime (tv);
  266. elapsed_time = (double)microsec / 1.0e6;
  267. if (result == STATE_OK) {
  268. if (check_critical_time && elapsed_time > (double) critical_time)
  269. result = STATE_CRITICAL;
  270. else if (check_warning_time && elapsed_time > (double) warning_time)
  271. result = STATE_WARNING;
  272. }
  273. printf (_("SMTP %s - %.3f sec. response time%s%s|%s\n"),
  274. state_text (result), elapsed_time,
  275. verbose?", ":"", verbose?buffer:"",
  276. fperfdata ("time", elapsed_time, "s",
  277. (int)check_warning_time, warning_time,
  278. (int)check_critical_time, critical_time,
  279. TRUE, 0, FALSE, 0));
  280. return result;
  281. }
  282. /* process command-line arguments */
  283. int
  284. process_arguments (int argc, char **argv)
  285. {
  286. int c;
  287. int option = 0;
  288. static struct option longopts[] = {
  289. {"hostname", required_argument, 0, 'H'},
  290. {"expect", required_argument, 0, 'e'},
  291. {"critical", required_argument, 0, 'c'},
  292. {"warning", required_argument, 0, 'w'},
  293. {"timeout", required_argument, 0, 't'},
  294. {"port", required_argument, 0, 'p'},
  295. {"from", required_argument, 0, 'f'},
  296. {"command", required_argument, 0, 'C'},
  297. {"response", required_argument, 0, 'R'},
  298. {"nocommand", required_argument, 0, 'n'},
  299. {"verbose", no_argument, 0, 'v'},
  300. {"version", no_argument, 0, 'V'},
  301. {"use-ipv4", no_argument, 0, '4'},
  302. {"use-ipv6", no_argument, 0, '6'},
  303. {"help", no_argument, 0, 'h'},
  304. {"starttls",no_argument,0,'S'},
  305. {"certificate",required_argument,0,'D'},
  306. {0, 0, 0, 0}
  307. };
  308. if (argc < 2)
  309. return ERROR;
  310. for (c = 1; c < argc; c++) {
  311. if (strcmp ("-to", argv[c]) == 0)
  312. strcpy (argv[c], "-t");
  313. else if (strcmp ("-wt", argv[c]) == 0)
  314. strcpy (argv[c], "-w");
  315. else if (strcmp ("-ct", argv[c]) == 0)
  316. strcpy (argv[c], "-c");
  317. }
  318. while (1) {
  319. c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:",
  320. longopts, &option);
  321. if (c == -1 || c == EOF)
  322. break;
  323. switch (c) {
  324. case 'H': /* hostname */
  325. if (is_host (optarg)) {
  326. server_address = optarg;
  327. }
  328. else {
  329. usage2 (_("Invalid hostname/address"), optarg);
  330. }
  331. break;
  332. case 'p': /* port */
  333. if (is_intpos (optarg))
  334. server_port = atoi (optarg);
  335. else
  336. usage4 (_("Port must be a positive integer"));
  337. break;
  338. case 'f': /* from argument */
  339. from_arg = optarg;
  340. smtp_use_dummycmd = 1;
  341. break;
  342. case 'e': /* server expect string on 220 */
  343. server_expect = optarg;
  344. break;
  345. case 'C': /* commands */
  346. if (ncommands >= command_size) {
  347. commands = realloc (commands, command_size+8);
  348. if (commands == NULL)
  349. die (STATE_UNKNOWN,
  350. _("Could not realloc() units [%d]\n"), ncommands);
  351. }
  352. commands[ncommands] = optarg;
  353. ncommands++;
  354. break;
  355. case 'R': /* server responses */
  356. if (nresponses >= response_size) {
  357. responses = realloc (responses, response_size+8);
  358. if (responses == NULL)
  359. die (STATE_UNKNOWN,
  360. _("Could not realloc() units [%d]\n"), nresponses);
  361. }
  362. responses[nresponses] = optarg;
  363. nresponses++;
  364. break;
  365. case 'c': /* critical time threshold */
  366. if (is_intnonneg (optarg)) {
  367. critical_time = atoi (optarg);
  368. check_critical_time = TRUE;
  369. }
  370. else {
  371. usage4 (_("Critical time must be a positive integer"));
  372. }
  373. break;
  374. case 'w': /* warning time threshold */
  375. if (is_intnonneg (optarg)) {
  376. warning_time = atoi (optarg);
  377. check_warning_time = TRUE;
  378. }
  379. else {
  380. usage4 (_("Warning time must be a positive integer"));
  381. }
  382. break;
  383. case 'v': /* verbose */
  384. verbose++;
  385. break;
  386. case 't': /* timeout */
  387. if (is_intnonneg (optarg)) {
  388. socket_timeout = atoi (optarg);
  389. }
  390. else {
  391. usage4 (_("Timeout interval must be a positive integer"));
  392. }
  393. break;
  394. case 'S':
  395. /* starttls */
  396. use_ssl = TRUE;
  397. break;
  398. case 'D':
  399. /* Check SSL cert validity */
  400. #ifdef HAVE_SSL
  401. if (!is_intnonneg (optarg))
  402. usage2 ("Invalid certificate expiration period",optarg);
  403. days_till_exp = atoi (optarg);
  404. check_cert = TRUE;
  405. #else
  406. usage (_("SSL support not available - install OpenSSL and recompile"));
  407. #endif
  408. break;
  409. case '4':
  410. address_family = AF_INET;
  411. break;
  412. case '6':
  413. #ifdef USE_IPV6
  414. address_family = AF_INET6;
  415. #else
  416. usage4 (_("IPv6 support not available"));
  417. #endif
  418. break;
  419. case 'V': /* version */
  420. print_revision (progname, revision);
  421. exit (STATE_OK);
  422. case 'h': /* help */
  423. print_help ();
  424. exit (STATE_OK);
  425. case '?': /* help */
  426. usage2 (_("Unknown argument"), optarg);
  427. }
  428. }
  429. c = optind;
  430. if (server_address == NULL) {
  431. if (argv[c]) {
  432. if (is_host (argv[c]))
  433. server_address = argv[c];
  434. else
  435. usage2 (_("Invalid hostname/address"), argv[c]);
  436. }
  437. else {
  438. asprintf (&server_address, "127.0.0.1");
  439. }
  440. }
  441. if (server_expect == NULL)
  442. server_expect = strdup (SMTP_EXPECT);
  443. if (mail_command == NULL)
  444. mail_command = strdup("MAIL ");
  445. if (from_arg==NULL)
  446. from_arg = strdup(" ");
  447. return validate_arguments ();
  448. }
  449. int
  450. validate_arguments (void)
  451. {
  452. return OK;
  453. }
  454. void
  455. print_help (void)
  456. {
  457. char *myport;
  458. asprintf (&myport, "%d", SMTP_PORT);
  459. print_revision (progname, revision);
  460. printf ("Copyright (c) 1999-2001 Ethan Galstad <nagios@nagios.org>\n");
  461. printf (COPYRIGHT, copyright, email);
  462. printf(_("This plugin will attempt to open an SMTP connection with the host.\n\n"));
  463. print_usage ();
  464. printf (_(UT_HELP_VRSN));
  465. printf (_(UT_HOST_PORT), 'p', myport);
  466. printf (_(UT_IPv46));
  467. printf (_("\
  468. -e, --expect=STRING\n\
  469. String to expect in first line of server response (default: '%s')\n\
  470. -n, nocommand\n\
  471. Suppress SMTP command\n\
  472. -C, --command=STRING\n\
  473. SMTP command (may be used repeatedly)\n\
  474. -R, --command=STRING\n\
  475. Expected response to command (may be used repeatedly)\n\
  476. -f, --from=STRING\n\
  477. FROM-address to include in MAIL command, required by Exchange 2000\n"),
  478. SMTP_EXPECT);
  479. #ifdef HAVE_SSL
  480. printf (_("\
  481. -D, --certificate=INTEGER\n\
  482. Minimum number of days a certificate has to be valid.\n\
  483. -S, --starttls\n\
  484. Use STARTTLS for the connection.\n"));
  485. #endif
  486. printf (_(UT_WARN_CRIT));
  487. printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
  488. printf (_(UT_VERBOSE));
  489. printf(_("\n\
  490. Successul connects return STATE_OK, refusals and timeouts return\n\
  491. STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful\n\
  492. connects, but incorrect reponse messages from the host result in\n\
  493. STATE_WARNING return values.\n"));
  494. printf (_(UT_SUPPORT));
  495. }
  496. void
  497. print_usage (void)
  498. {
  499. printf ("\
  500. Usage: %s -H host [-p port] [-e expect] [-C command] [-f from addr]\n\
  501. [-w warn] [-c crit] [-t timeout] [-S] [-D days] [-n] [-v] [-4|-6]\n", progname);
  502. }
  503. #ifdef HAVE_SSL
  504. int
  505. connect_STARTTLS (void)
  506. {
  507. SSL_METHOD *meth;
  508. /* Initialize SSL context */
  509. SSLeay_add_ssl_algorithms ();
  510. meth = SSLv2_client_method ();
  511. SSL_load_error_strings ();
  512. if ((ctx = SSL_CTX_new (meth)) == NULL)
  513. {
  514. printf(_("CRITICAL - Cannot create SSL context.\n"));
  515. return STATE_CRITICAL;
  516. }
  517. /* do the SSL handshake */
  518. if ((ssl = SSL_new (ctx)) != NULL)
  519. {
  520. SSL_set_fd (ssl, sd);
  521. /* original version checked for -1
  522. I look for success instead (1) */
  523. if (SSL_connect (ssl) == 1)
  524. return OK;
  525. ERR_print_errors_fp (stderr);
  526. }
  527. else
  528. {
  529. printf (_("CRITICAL - Cannot initiate SSL handshake.\n"));
  530. }
  531. /* this causes a seg faul
  532. not sure why, being sloppy
  533. and commenting it out */
  534. /* SSL_free (ssl); */
  535. SSL_CTX_free(ctx);
  536. my_close();
  537. return STATE_CRITICAL;
  538. }
  539. int
  540. check_certificate (X509 ** certificate)
  541. {
  542. ASN1_STRING *tm;
  543. int offset;
  544. struct tm stamp;
  545. int days_left;
  546. /* Retrieve timestamp of certificate */
  547. tm = X509_get_notAfter (*certificate);
  548. /* Generate tm structure to process timestamp */
  549. if (tm->type == V_ASN1_UTCTIME) {
  550. if (tm->length < 10) {
  551. printf (_("CRITICAL - Wrong time format in certificate.\n"));
  552. return STATE_CRITICAL;
  553. }
  554. else {
  555. stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0');
  556. if (stamp.tm_year < 50)
  557. stamp.tm_year += 100;
  558. offset = 0;
  559. }
  560. }
  561. else {
  562. if (tm->length < 12) {
  563. printf (_("CRITICAL - Wrong time format in certificate.\n"));
  564. return STATE_CRITICAL;
  565. }
  566. else {
  567. stamp.tm_year =
  568. (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 +
  569. (tm->data[2] - '0') * 10 + (tm->data[3] - '0');
  570. stamp.tm_year -= 1900;
  571. offset = 2;
  572. }
  573. }
  574. stamp.tm_mon =
  575. (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1;
  576. stamp.tm_mday =
  577. (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0');
  578. stamp.tm_hour =
  579. (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0');
  580. stamp.tm_min =
  581. (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0');
  582. stamp.tm_sec = 0;
  583. stamp.tm_isdst = -1;
  584. days_left = (mktime (&stamp) - time (NULL)) / 86400;
  585. snprintf
  586. (timestamp, 16, "%02d/%02d/%04d %02d:%02d",
  587. stamp.tm_mon + 1,
  588. stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min);
  589. if (days_left > 0 && days_left <= days_till_exp) {
  590. printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp);
  591. return STATE_WARNING;
  592. }
  593. if (days_left < 0) {
  594. printf ("Certificate expired on %s.\n", timestamp);
  595. return STATE_CRITICAL;
  596. }
  597. if (days_left == 0) {
  598. printf ("Certificate expires today (%s).\n", timestamp);
  599. return STATE_WARNING;
  600. }
  601. printf ("Certificate will expire on %s.\n", timestamp);
  602. return STATE_OK;
  603. }
  604. #endif
  605. int
  606. myrecv (void)
  607. {
  608. int i;
  609. #ifdef HAVE_SSL
  610. if (use_ssl) {
  611. i = SSL_read (ssl, buffer, MAXBUF - 1);
  612. }
  613. else {
  614. #endif
  615. i = read (sd, buffer, MAXBUF - 1);
  616. #ifdef HAVE_SSL
  617. }
  618. #endif
  619. return i;
  620. }
  621. int
  622. my_close (void)
  623. {
  624. #ifdef HAVE_SSL
  625. if (use_ssl == TRUE) {
  626. SSL_shutdown (ssl);
  627. SSL_free (ssl);
  628. SSL_CTX_free (ctx);
  629. return 0;
  630. }
  631. else {
  632. #endif
  633. return close(sd);
  634. #ifdef HAVE_SSL
  635. }
  636. #endif
  637. }