check_smtp.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  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[20] = "";
  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. /* send the HELO command */
  154. send(sd, helocmd, strlen(helocmd), 0);
  155. /* allow for response to helo command to reach us */
  156. read (sd, buffer, MAXBUF - 1);
  157. #ifdef HAVE_SSL
  158. if(use_ssl) {
  159. /* send the STARTTLS command */
  160. send(sd, SMTP_STARTTLS, strlen(SMTP_STARTTLS), 0);
  161. recv(sd,buffer, MAX_INPUT_BUFFER-1, 0); /* wait for it */
  162. if (!strstr (buffer, server_expect)) {
  163. printf (_("Server does not support STARTTLS\n"));
  164. return STATE_UNKNOWN;
  165. }
  166. if(connect_STARTTLS() != OK) {
  167. printf (_("CRITICAL - Cannot create SSL context.\n"));
  168. return STATE_CRITICAL;
  169. }
  170. if ( check_cert ) {
  171. if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) {
  172. result = check_certificate (&server_cert);
  173. X509_free(server_cert);
  174. }
  175. else {
  176. printf (_("CRITICAL - Cannot retrieve server certificate.\n"));
  177. result = STATE_CRITICAL;
  178. }
  179. my_close();
  180. return result;
  181. }
  182. }
  183. #endif
  184. /* sendmail will syslog a "NOQUEUE" error if session does not attempt
  185. * to do something useful. This can be prevented by giving a command
  186. * even if syntax is illegal (MAIL requires a FROM:<...> argument)
  187. *
  188. * According to rfc821 you can include a null reversepath in the from command
  189. * - but a log message is generated on the smtp server.
  190. *
  191. * You can disable sending mail_command with '--nocommand'
  192. * Use the -f option to provide a FROM address
  193. */
  194. if (smtp_use_dummycmd) {
  195. #ifdef HAVE_SSL
  196. if (use_ssl)
  197. SSL_write(ssl, cmd_str, strlen(cmd_str));
  198. else
  199. #endif
  200. send(sd, cmd_str, strlen(cmd_str), 0);
  201. myrecv();
  202. if (verbose)
  203. printf("%s", buffer);
  204. }
  205. while (n < ncommands) {
  206. asprintf (&cmd_str, "%s%s", commands[n], "\r\n");
  207. #ifdef HAVE_SSL
  208. if (use_ssl)
  209. SSL_write(ssl,cmd_str, strlen(cmd_str));
  210. else
  211. #endif
  212. send(sd, cmd_str, strlen(cmd_str), 0);
  213. myrecv();
  214. if (verbose)
  215. printf("%s", buffer);
  216. strip (buffer);
  217. if (n < nresponses) {
  218. #ifdef HAVE_REGEX_H
  219. cflags |= REG_EXTENDED | REG_NOSUB | REG_NEWLINE;
  220. errcode = regcomp (&preg, responses[n], cflags);
  221. if (errcode != 0) {
  222. regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
  223. printf (_("Could Not Compile Regular Expression"));
  224. return ERROR;
  225. }
  226. excode = regexec (&preg, buffer, 10, pmatch, eflags);
  227. if (excode == 0) {
  228. result = STATE_OK;
  229. }
  230. else if (excode == REG_NOMATCH) {
  231. result = STATE_WARNING;
  232. printf (_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text (result), buffer, commands[n]);
  233. }
  234. else {
  235. regerror (excode, &preg, errbuf, MAX_INPUT_BUFFER);
  236. printf (_("Execute Error: %s\n"), errbuf);
  237. result = STATE_UNKNOWN;
  238. }
  239. #else
  240. if (strstr(buffer, responses[n])!=buffer) {
  241. result = STATE_WARNING;
  242. printf (_("SMTP %s - Invalid response '%s' to command '%s'\n"), state_text (result), buffer, commands[n]);
  243. }
  244. #endif
  245. }
  246. n++;
  247. }
  248. /* tell the server we're done */
  249. #ifdef HAVE_SSL
  250. if (use_ssl)
  251. SSL_write(ssl,SMTP_QUIT, strlen (SMTP_QUIT));
  252. else
  253. #endif
  254. send (sd, SMTP_QUIT, strlen (SMTP_QUIT), 0);
  255. /* finally close the connection */
  256. close (sd);
  257. }
  258. /* reset the alarm */
  259. alarm (0);
  260. microsec = deltime (tv);
  261. elapsed_time = (double)microsec / 1.0e6;
  262. if (result == STATE_OK) {
  263. if (check_critical_time && elapsed_time > (double) critical_time)
  264. result = STATE_CRITICAL;
  265. else if (check_warning_time && elapsed_time > (double) warning_time)
  266. result = STATE_WARNING;
  267. }
  268. printf (_("SMTP %s - %.3f sec. response time%s%s|%s\n"),
  269. state_text (result), elapsed_time,
  270. verbose?", ":"", verbose?buffer:"",
  271. fperfdata ("time", elapsed_time, "s",
  272. (int)check_warning_time, warning_time,
  273. (int)check_critical_time, critical_time,
  274. TRUE, 0, FALSE, 0));
  275. return result;
  276. }
  277. /* process command-line arguments */
  278. int
  279. process_arguments (int argc, char **argv)
  280. {
  281. int c;
  282. int option = 0;
  283. static struct option longopts[] = {
  284. {"hostname", required_argument, 0, 'H'},
  285. {"expect", required_argument, 0, 'e'},
  286. {"critical", required_argument, 0, 'c'},
  287. {"warning", required_argument, 0, 'w'},
  288. {"timeout", required_argument, 0, 't'},
  289. {"port", required_argument, 0, 'p'},
  290. {"from", required_argument, 0, 'f'},
  291. {"command", required_argument, 0, 'C'},
  292. {"response", required_argument, 0, 'R'},
  293. {"nocommand", required_argument, 0, 'n'},
  294. {"verbose", no_argument, 0, 'v'},
  295. {"version", no_argument, 0, 'V'},
  296. {"use-ipv4", no_argument, 0, '4'},
  297. {"use-ipv6", no_argument, 0, '6'},
  298. {"help", no_argument, 0, 'h'},
  299. {"starttls",no_argument,0,'S'},
  300. {"certificate",required_argument,0,'D'},
  301. {0, 0, 0, 0}
  302. };
  303. if (argc < 2)
  304. return ERROR;
  305. for (c = 1; c < argc; c++) {
  306. if (strcmp ("-to", argv[c]) == 0)
  307. strcpy (argv[c], "-t");
  308. else if (strcmp ("-wt", argv[c]) == 0)
  309. strcpy (argv[c], "-w");
  310. else if (strcmp ("-ct", argv[c]) == 0)
  311. strcpy (argv[c], "-c");
  312. }
  313. while (1) {
  314. c = getopt_long (argc, argv, "+hVv46t:p:f:e:c:w:H:C:R:SD:",
  315. longopts, &option);
  316. if (c == -1 || c == EOF)
  317. break;
  318. switch (c) {
  319. case 'H': /* hostname */
  320. if (is_host (optarg)) {
  321. server_address = optarg;
  322. }
  323. else {
  324. usage2 (_("Invalid hostname/address"), optarg);
  325. }
  326. break;
  327. case 'p': /* port */
  328. if (is_intpos (optarg))
  329. server_port = atoi (optarg);
  330. else
  331. usage4 (_("Port must be a positive integer"));
  332. break;
  333. case 'f': /* from argument */
  334. from_arg = optarg;
  335. smtp_use_dummycmd = 1;
  336. break;
  337. case 'e': /* server expect string on 220 */
  338. server_expect = optarg;
  339. break;
  340. case 'C': /* commands */
  341. if (ncommands >= command_size) {
  342. commands = realloc (commands, command_size+8);
  343. if (commands == NULL)
  344. die (STATE_UNKNOWN,
  345. _("Could not realloc() units [%d]\n"), ncommands);
  346. }
  347. commands[ncommands] = optarg;
  348. ncommands++;
  349. break;
  350. case 'R': /* server responses */
  351. if (nresponses >= response_size) {
  352. responses = realloc (responses, response_size+8);
  353. if (responses == NULL)
  354. die (STATE_UNKNOWN,
  355. _("Could not realloc() units [%d]\n"), nresponses);
  356. }
  357. responses[nresponses] = optarg;
  358. nresponses++;
  359. break;
  360. case 'c': /* critical time threshold */
  361. if (is_intnonneg (optarg)) {
  362. critical_time = atoi (optarg);
  363. check_critical_time = TRUE;
  364. }
  365. else {
  366. usage4 (_("Critical time must be a positive integer"));
  367. }
  368. break;
  369. case 'w': /* warning time threshold */
  370. if (is_intnonneg (optarg)) {
  371. warning_time = atoi (optarg);
  372. check_warning_time = TRUE;
  373. }
  374. else {
  375. usage4 (_("Warning time must be a positive integer"));
  376. }
  377. break;
  378. case 'v': /* verbose */
  379. verbose++;
  380. break;
  381. case 't': /* timeout */
  382. if (is_intnonneg (optarg)) {
  383. socket_timeout = atoi (optarg);
  384. }
  385. else {
  386. usage4 (_("Timeout interval must be a positive integer"));
  387. }
  388. break;
  389. case 'S':
  390. /* starttls */
  391. use_ssl = TRUE;
  392. break;
  393. case 'D':
  394. /* Check SSL cert validity */
  395. #ifdef HAVE_SSL
  396. if (!is_intnonneg (optarg))
  397. usage2 ("Invalid certificate expiration period",optarg);
  398. days_till_exp = atoi (optarg);
  399. check_cert = TRUE;
  400. #else
  401. usage (_("SSL support not available - install OpenSSL and recompile"));
  402. #endif
  403. break;
  404. case '4':
  405. address_family = AF_INET;
  406. break;
  407. case '6':
  408. #ifdef USE_IPV6
  409. address_family = AF_INET6;
  410. #else
  411. usage4 (_("IPv6 support not available"));
  412. #endif
  413. break;
  414. case 'V': /* version */
  415. print_revision (progname, revision);
  416. exit (STATE_OK);
  417. case 'h': /* help */
  418. print_help ();
  419. exit (STATE_OK);
  420. case '?': /* help */
  421. usage2 (_("Unknown argument"), optarg);
  422. }
  423. }
  424. c = optind;
  425. if (server_address == NULL) {
  426. if (argv[c]) {
  427. if (is_host (argv[c]))
  428. server_address = argv[c];
  429. else
  430. usage2 (_("Invalid hostname/address"), argv[c]);
  431. }
  432. else {
  433. asprintf (&server_address, "127.0.0.1");
  434. }
  435. }
  436. if (server_expect == NULL)
  437. server_expect = strdup (SMTP_EXPECT);
  438. if (mail_command == NULL)
  439. mail_command = strdup("MAIL ");
  440. if (from_arg==NULL)
  441. from_arg = strdup(" ");
  442. return validate_arguments ();
  443. }
  444. int
  445. validate_arguments (void)
  446. {
  447. return OK;
  448. }
  449. void
  450. print_help (void)
  451. {
  452. char *myport;
  453. asprintf (&myport, "%d", SMTP_PORT);
  454. print_revision (progname, revision);
  455. printf ("Copyright (c) 1999-2001 Ethan Galstad <nagios@nagios.org>\n");
  456. printf (COPYRIGHT, copyright, email);
  457. printf(_("This plugin will attempt to open an SMTP connection with the host.\n\n"));
  458. print_usage ();
  459. printf (_(UT_HELP_VRSN));
  460. printf (_(UT_HOST_PORT), 'p', myport);
  461. printf (_(UT_IPv46));
  462. printf (_("\
  463. -e, --expect=STRING\n\
  464. String to expect in first line of server response (default: '%s')\n\
  465. -n, nocommand\n\
  466. Suppress SMTP command\n\
  467. -C, --command=STRING\n\
  468. SMTP command (may be used repeatedly)\n\
  469. -R, --command=STRING\n\
  470. Expected response to command (may be used repeatedly)\n\
  471. -f, --from=STRING\n\
  472. FROM-address to include in MAIL command, required by Exchange 2000\n"),
  473. SMTP_EXPECT);
  474. #ifdef HAVE_SSL
  475. printf (_("\
  476. -D, --certificate=INTEGER\n\
  477. Minimum number of days a certificate has to be valid.\n\
  478. -S, --starttls\n\
  479. Use STARTTLS for the connection.\n"));
  480. #endif
  481. printf (_(UT_WARN_CRIT));
  482. printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
  483. printf (_(UT_VERBOSE));
  484. printf(_("\n\
  485. Successul connects return STATE_OK, refusals and timeouts return\n\
  486. STATE_CRITICAL, other errors return STATE_UNKNOWN. Successful\n\
  487. connects, but incorrect reponse messages from the host result in\n\
  488. STATE_WARNING return values.\n"));
  489. printf (_(UT_SUPPORT));
  490. }
  491. void
  492. print_usage (void)
  493. {
  494. printf ("\
  495. Usage: %s -H host [-p port] [-e expect] [-C command] [-f from addr]\n\
  496. [-w warn] [-c crit] [-t timeout] [-S] [-D days] [-n] [-v] [-4|-6]\n", progname);
  497. }
  498. #ifdef HAVE_SSL
  499. int
  500. connect_STARTTLS (void)
  501. {
  502. SSL_METHOD *meth;
  503. /* Initialize SSL context */
  504. SSLeay_add_ssl_algorithms ();
  505. meth = SSLv2_client_method ();
  506. SSL_load_error_strings ();
  507. if ((ctx = SSL_CTX_new (meth)) == NULL)
  508. {
  509. printf(_("CRITICAL - Cannot create SSL context.\n"));
  510. return STATE_CRITICAL;
  511. }
  512. /* do the SSL handshake */
  513. if ((ssl = SSL_new (ctx)) != NULL)
  514. {
  515. SSL_set_fd (ssl, sd);
  516. /* original version checked for -1
  517. I look for success instead (1) */
  518. if (SSL_connect (ssl) == 1)
  519. return OK;
  520. ERR_print_errors_fp (stderr);
  521. }
  522. else
  523. {
  524. printf (_("CRITICAL - Cannot initiate SSL handshake.\n"));
  525. }
  526. /* this causes a seg faul
  527. not sure why, being sloppy
  528. and commenting it out */
  529. /* SSL_free (ssl); */
  530. SSL_CTX_free(ctx);
  531. my_close();
  532. return STATE_CRITICAL;
  533. }
  534. int
  535. check_certificate (X509 ** certificate)
  536. {
  537. ASN1_STRING *tm;
  538. int offset;
  539. struct tm stamp;
  540. int days_left;
  541. /* Retrieve timestamp of certificate */
  542. tm = X509_get_notAfter (*certificate);
  543. /* Generate tm structure to process timestamp */
  544. if (tm->type == V_ASN1_UTCTIME) {
  545. if (tm->length < 10) {
  546. printf (_("CRITICAL - Wrong time format in certificate.\n"));
  547. return STATE_CRITICAL;
  548. }
  549. else {
  550. stamp.tm_year = (tm->data[0] - '0') * 10 + (tm->data[1] - '0');
  551. if (stamp.tm_year < 50)
  552. stamp.tm_year += 100;
  553. offset = 0;
  554. }
  555. }
  556. else {
  557. if (tm->length < 12) {
  558. printf (_("CRITICAL - Wrong time format in certificate.\n"));
  559. return STATE_CRITICAL;
  560. }
  561. else {
  562. stamp.tm_year =
  563. (tm->data[0] - '0') * 1000 + (tm->data[1] - '0') * 100 +
  564. (tm->data[2] - '0') * 10 + (tm->data[3] - '0');
  565. stamp.tm_year -= 1900;
  566. offset = 2;
  567. }
  568. }
  569. stamp.tm_mon =
  570. (tm->data[2 + offset] - '0') * 10 + (tm->data[3 + offset] - '0') - 1;
  571. stamp.tm_mday =
  572. (tm->data[4 + offset] - '0') * 10 + (tm->data[5 + offset] - '0');
  573. stamp.tm_hour =
  574. (tm->data[6 + offset] - '0') * 10 + (tm->data[7 + offset] - '0');
  575. stamp.tm_min =
  576. (tm->data[8 + offset] - '0') * 10 + (tm->data[9 + offset] - '0');
  577. stamp.tm_sec = 0;
  578. stamp.tm_isdst = -1;
  579. days_left = (mktime (&stamp) - time (NULL)) / 86400;
  580. snprintf
  581. (timestamp, sizeof(timestamp), "%02d/%02d/%04d %02d:%02d",
  582. stamp.tm_mon + 1,
  583. stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min);
  584. if (days_left > 0 && days_left <= days_till_exp) {
  585. printf ("Certificate expires in %d day(s) (%s).\n", days_left, timestamp);
  586. return STATE_WARNING;
  587. }
  588. if (days_left < 0) {
  589. printf ("Certificate expired on %s.\n", timestamp);
  590. return STATE_CRITICAL;
  591. }
  592. if (days_left == 0) {
  593. printf ("Certificate expires today (%s).\n", timestamp);
  594. return STATE_WARNING;
  595. }
  596. printf ("Certificate will expire on %s.\n", timestamp);
  597. return STATE_OK;
  598. }
  599. #endif
  600. int
  601. myrecv (void)
  602. {
  603. int i;
  604. #ifdef HAVE_SSL
  605. if (use_ssl) {
  606. i = SSL_read (ssl, buffer, MAXBUF - 1);
  607. }
  608. else {
  609. #endif
  610. i = read (sd, buffer, MAXBUF - 1);
  611. #ifdef HAVE_SSL
  612. }
  613. #endif
  614. return i;
  615. }
  616. int
  617. my_close (void)
  618. {
  619. #ifdef HAVE_SSL
  620. if (use_ssl == TRUE) {
  621. SSL_shutdown (ssl);
  622. SSL_free (ssl);
  623. SSL_CTX_free (ctx);
  624. return 0;
  625. }
  626. else {
  627. #endif
  628. return close(sd);
  629. #ifdef HAVE_SSL
  630. }
  631. #endif
  632. }