Advertisement
joshtrier

Untitled

Aug 2nd, 2011
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 23.94 KB | None | 0 0
  1. #!/bin/bash
  2. #
  3. # Program: SSL Certificate Check <ssl-cert-check>
  4. #
  5. # Source code home: http://prefetch.net/code/ssl-cert-check
  6. #
  7. # Documentation: http://prefetch.net/articles/checkcertificate.html
  8. #
  9. # Author: Matty < matty91 at gmail dot com >
  10. #
  11. # Current Version: 3.21
  12. #
  13. # Revision History:
  14.  
  15. # Version 3.21
  16. #   - Adjust e-mail checking to avoid exiting if notifications aren't enabled -- Nick Anderson
  17. #   - Added the number of days until expiration to the Nagios output -- Nick Anderson
  18. #
  19. # Version 3.20
  20. #   - Fixed a bug in certificate length checking -- Tim Nowaczyk
  21. #
  22. # Version 3.19
  23. #   - Added check to verify the certificate retrieved is valid
  24. #
  25. # Version 3.18
  26. #   - Add support for connecting to FTP servers -- Paul A Sand
  27. #
  28. # Version 3.17
  29. #   - Add support for connecting to imap servers -- Joerg Pareigis
  30. #
  31. # Version 3.16
  32. #   - Add support for connecting to the mail sbmission port -- Luis E. Munoz
  33. #
  34. # Version 3.15
  35. #   - Adjusted the file checking logic to use the correct certificate -- Maciej Szudejko
  36. #   - Add sbin to the default search paths for OpenBSD compatibility -- Alex Popov
  37. #   - Use cut instead of substring processing to ensure compatibility -- Alex Popov
  38. #
  39. # Version 3.14
  40. #   - Fixed the Common Name parser to handle DN's where the CN is not the last item
  41. #     eg. EmailAddr -- Jason Brothers
  42. #   - Added the ability to grab the serial number -- Jason Brothers
  43. #   - Added the "-b" option to print results without a header -- Jason Brothers
  44. #   - Added the "-v" option for certificate validation -- Jason Brothers
  45. #
  46. # Version 3.13
  47. #   - Updated the subject line to include the hostname as well as
  48. #     the common name embedded in the X509 certificate (if it's
  49. #     available) -- idea proposed by Mike Burns
  50. #
  51. #  Version 3.12
  52. #   - Updated the license to allow redistribution and modification
  53. #
  54. #  Version 3.11
  55. #   - Added ability to comment out lines in files passed
  56. #     to the "-f" option -- Brett Stauner
  57. #   - Fixed comment next to file processing logic
  58. #
  59. #  Version 3.10
  60. #   - Fixed POP3 port -- Simon Matter
  61. #
  62. #  Version 3.9
  63. #    - Switched binary location logic to use which utility
  64. #
  65. #  Version 3.8
  66. #    - Fixed display on 80 column displays
  67. #    - Cleaned up the formatting
  68. #
  69. #  Version 3.7
  70. #    - Fixed bug in NAGIOS tests -- Ben Allen
  71. #
  72. #  Version 3.6
  73. #    - Added support for certificates stored in PKCS#12 databases -- Ken Gallo
  74. #    - Cleaned up comments
  75. #    - Adjusted variables to be more consistent
  76. #
  77. #  Version 3.5
  78. #    - Added support for NAGIOS -- Quanah Gibson-Mount
  79. #    - Added additional checks for mail -- Quanah Gibson-Mount
  80. #    - Convert tabs to spaces -- Quanah Gibson-Mount
  81. #    - Cleaned up usage() routine
  82. #    - Added additional checks for openssl
  83. #
  84. #  Version 3.4
  85. #   - Added a missing "{" to line 364 -- Ken Gallo
  86. #   - Move mktemp to the start of the main body to avoid errors
  87. #   - Adjusted default binary paths to make sure the script just works
  88. #     w/ Solaris, BSD and Linux hosts
  89. #
  90. #  Version 3.3
  91. #   - Added common name from X.509 certificate file to E-mail body / header -- Doug Curtis
  92. #   - Fixed several documentation errors
  93. #   - Use mktemp to create temporary files
  94. #   - Convert printf, sed and awk to variables
  95. #   - Check for printf, sed, awk and mktemp binaries
  96. #   - Add additional logic to make sure mktemp returned a valid temporary file
  97. #
  98. #  Version 3.2
  99. #   - Added option to list certificates in the file passed to "-f".
  100. #
  101. #  Version 3.1
  102. #   - Added handling for starttls for smtp -- Marco Amrein
  103. #   - Added handling for starttls for pop3 (without s) -- Marco Amrein
  104. #   - Removed extra spacing at end of script
  105. #
  106. #  Version 3.0
  107. #   - Added "-i" option to print certificate issuer  
  108. #   - Removed $0 from Subject line of outbound e-mails
  109. #   - Fixed some typographical errors
  110. #   - Removed redundant "-b" option
  111. #
  112. #  Version 2.0
  113. #    - Fixed an issue with e-mails formatting incorrectly
  114. #    - Added additional space to host column -- Darren-Perot Spruell
  115. #    - Replaced GNU date dependency with CHRIS F. A. JOHNSON's
  116. #      date2julian shell function. This routine can be found on
  117. #      page 170 of Chris's book "Shell Scripting Recipes: A
  118. #      Problem-Solution Approach," ISBN #1590594711. Julian function
  119. #      was created based on a post to comp.unix.shell by Tapani Tarvainen.
  120. #    - Cleaned up function descriptions
  121. #    - Removed several lines of redundant code
  122. #    - Adjusted the help message
  123. #      
  124. #   Version 1.1
  125. #    - Added "-c" flag to report expiration status of a PEM encoded
  126. #      certificate -- Hampus Lundqvist
  127. #    - Updated the prints messages to display the reason a connection
  128. #      failed (connection refused, connection timeout, bad cert, etc)
  129. #    - Updated the GNU date checking routines
  130. #    - Added checks for each binary required
  131. #    - Added checks for connection timeouts
  132. #    - Added checks for GNU date
  133. #    - Added a "-h" option
  134. #    - Cleaned up the documentation
  135. #
  136. #  Version 1.0
  137. #      Initial Release
  138. #
  139. # Last Updated: 11-23-2010
  140. #
  141. # Purpose:
  142. #  ssl-cert-check checks to see if a digital certificate in X.509 format
  143. #  has expired. ssl-cert-check can be run in interactive and batch mode,
  144. #  and provides facilities to alarm if a certificate is about to expire.
  145. #
  146. # License:
  147. #  This program is free software; you can redistribute it and/or modify
  148. #  it under the terms of the GNU General Public License as published by
  149. #  the Free Software Foundation; either version 2 of the License, or
  150. #  (at your option) any later version.
  151. #
  152. #  This program is distributed in the hope that it will be useful,
  153. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  154. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  155. #  GNU General Public License for more details.
  156. #
  157. # Requirements:
  158. #   Requires openssl
  159. #
  160. # Installation:
  161. #   Copy the shell script to a suitable location
  162. #
  163. # Tested platforms:
  164. #  -- Solaris 9 using /bin/bash
  165. #  -- Solaris 10 using /bin/bash
  166. #  -- OS X 10.4.2 using /bin/sh
  167. #  -- OpenBSD using /bin/sh
  168. #  -- FreeBSD using /bin/sh
  169. #  -- Redhat Enterprise Linux 3, 4, 5 & 6
  170. #
  171. # Usage:
  172. #  Refer to the usage() sub-routine, or invoke ssl-cert-check
  173. #  with the "-h" option.
  174. #
  175. # Examples:
  176. #   Please refer to the following site for documentation and
  177. #   examples:
  178. #      http://prefetch.net/articles/checkcertificate.html
  179. #
  180.  
  181. PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/ssl/bin:/usr/sfw/bin
  182. export PATH
  183.  
  184. # Who to page when an expired certificate is detected (cmdline: -e)
  185. ADMIN="root"
  186.  
  187. # Number of days in the warning threshhold  (cmdline: -x)
  188. WARNDAYS=30
  189.  
  190. # If QUIET is set to TRUE, don't print anything on the console (cmdline: -q)
  191. QUIET="FALSE"
  192.  
  193. # Don't send E-mail by default (cmdline: -a)
  194. ALARM="FALSE"
  195.  
  196. # Don't run as a Nagios plugin by default (cmdline: -n)
  197. NAGIOS="FALSE"
  198.  
  199. # NULL out the PKCSDBPASSWD variable for later use (cmdline: -k)
  200. PKCSDBPASSWD=""
  201.  
  202. # Location of system binaries
  203. AWK=$(which awk)
  204. DATE=$(which date)
  205. GREP=$(which grep)
  206. OPENSSL=$(which openssl)
  207. PRINTF=$(which printf)
  208. SED=$(which sed)
  209. MKTEMP=$(which mktemp)
  210.  
  211. # Return code used by nagios. Initialize to 0.
  212. RETCODE=0
  213.  
  214. # Set the default umask to be somewhat restrictive
  215. umask 077
  216.  
  217. #############################################################################
  218. # Purpose: Convert a date from MONTH-DAY-YEAR to Julian format
  219. # Acknowledgements: Code was adapted from examples in the book
  220. #                   "Shell Scripting Recipes: A Problem-Solution Approach"
  221. #                   ( ISBN 1590594711 )
  222. # Arguments:
  223. #   $1 -> Month (e.g., 06)
  224. #   $2 -> Day   (e.g., 08)
  225. #   $3 -> Year  (e.g., 2006)
  226. #############################################################################
  227. date2julian() {
  228.  
  229.     if [ "${1} != "" ] && [ "${2} != ""  ] && [ "${3}" != "" ]
  230.     then
  231.         ## Since leap years add aday at the end of February,
  232.         ## calculations are done from 1 March 0000 (a fictional year)
  233.         d2j_tmpmonth=$((12 * ${3} + ${1} - 3))
  234.        
  235.         ## If it is not yet March, the year is changed to the previous year
  236.         d2j_tmpyear=$(( ${d2j_tmpmonth} / 12))
  237.        
  238.         ## The number of days from 1 March 0000 is calculated
  239.         ## and the number of days from 1 Jan. 4713BC is added
  240.         echo $(( (734 * ${d2j_tmpmonth} + 15) / 24
  241.                  - 2 * ${d2j_tmpyear} + ${d2j_tmpyear}/4
  242.                  - ${d2j_tmpyear}/100 + ${d2j_tmpyear}/400 + $2 + 1721119 ))
  243.     else
  244.         echo 0
  245.     fi
  246. }
  247.  
  248. #############################################################################
  249. # Purpose: Convert a string month into an integer representation
  250. # Arguments:
  251. #   $1 -> Month name (e.g., Sep)
  252. #############################################################################
  253. getmonth()
  254. {
  255.     case ${1} in
  256.         Jan) echo 1 ;;
  257.         Feb) echo 2 ;;
  258.         Mar) echo 3 ;;
  259.         Apr) echo 4 ;;
  260.         May) echo 5 ;;
  261.         Jun) echo 6 ;;
  262.         Jul) echo 7 ;;
  263.         Aug) echo 8 ;;
  264.         Sep) echo 9 ;;
  265.         Oct) echo 10 ;;
  266.         Nov) echo 11 ;;
  267.         Dec) echo 12 ;;
  268.           *) echo  0 ;;
  269.     esac
  270. }
  271.  
  272. #############################################################################
  273. # Purpose: Calculate the number of seconds between two dates
  274. # Arguments:
  275. #   $1 -> Date #1
  276. #   $2 -> Date #2
  277. #############################################################################
  278. date_diff()
  279. {
  280.     if [ "${1}" != "" ] &&  [ "${2}" != "" ]
  281.     then
  282.         echo $((${2} - ${1}))
  283.     else
  284.         echo 0
  285.     fi
  286. }
  287.  
  288. #####################################################################
  289. # Purpose: Print a line with the expiraton interval
  290. # Arguments:
  291. #   $1 -> Hostname
  292. #   $2 -> TCP Port
  293. #   $3 -> Status of certification (e.g., expired or valid)
  294. #   $4 -> Date when certificate will expire
  295. #   $5 -> Days left until the certificate will expire
  296. #   $6 -> Issuer of the certificate
  297. #####################################################################
  298. prints()
  299. {
  300.     if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
  301.     then
  302.         MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }')
  303.         if [ "${NAGIOS}" == "TRUE" ]
  304.         then
  305.             ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$MIN_DATE" \|days="$5"
  306.         else
  307.             ${PRINTF} "%-35s %-17s %-8s %-11s %-4s %-30s\n" "$1:$2" "$6" "$3" "$MIN_DATE" "$5"
  308.         fi
  309.     elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
  310.     then
  311.         ${PRINTF} "%-35s %-35s %-32s %-17s\n" "$1:$2" "$7" "$8" "$6"
  312.  
  313.     elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
  314.     then
  315.         MIN_DATE=$(echo $4 | ${AWK} '{ print $1, $2, $4 }')
  316.         if [ "${NAGIOS}" == "TRUE" ]
  317.         then
  318.             ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$MIN_DATE" \|days="$5"
  319.         else
  320.             ${PRINTF} "%-47s %-12s %-12s %-4s %-30s\n" "$1:$2" "$3" "$MIN_DATE" "$5"
  321.         fi  
  322.     elif [ "${QUIET}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
  323.     then
  324.         ${PRINTF} "%-35s %-35s %-32s\n" "$1:$2" "$7" "$8"
  325.     fi
  326. }
  327.  
  328.  
  329. ####################################################
  330. # Purpose: Print a heading with the relevant columns
  331. # Arguments:
  332. #   None
  333. ####################################################
  334. print_heading()
  335. {
  336.     if [ "${NOHEADER}" != "TRUE" ]
  337.     then
  338.        if [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
  339.        then
  340.            ${PRINTF} "\n%-35s %-17s %-8s %-11s %-4s\n" "Host" "Issuer" "Status" "Expires" "Days"
  341.            echo "----------------------------------- ----------------- -------- ----------- ----"
  342.  
  343.        elif [ "${QUIET}" != "TRUE" ] && [ "${ISSUER}" = "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
  344.        then
  345.            ${PRINTF} "\n%-35s %-35s %-32s %-17s\n" "Host" "Common Name" "Serial #" "Issuer"
  346.            echo "----------------------------------- ----------------------------------- -------------------------------- -----------------"
  347.    
  348.        elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" != "TRUE" ]
  349.        then
  350.            ${PRINTF} "\n%-47s %-12s %-12s %-4s\n" "Host" "Status" "Expires" "Days"
  351.            echo "----------------------------------------------- ------------ ------------ ----"
  352.    
  353.        elif [ "${QUIET}" != "TRUE" ] && [ "${NAGIOS}" != "TRUE" ] && [ "${VALIDATION}" == "TRUE" ]
  354.        then
  355.            ${PRINTF} "\n%-35s %-35s %-32s\n" "Host" "Common Name" "Serial #"
  356.            echo "----------------------------------- ----------------------------------- --------------------------------"
  357.         fi
  358.     fi
  359. }
  360.  
  361.  
  362. ##########################################
  363. # Purpose: Describe how the script works
  364. # Arguments:
  365. #   None
  366. ##########################################
  367. usage()
  368. {
  369.     echo "Usage: $0 [ -e email address ] [ -x days ] [-q] [-a] [-b] [-h] [-i] [-n] [-v]"
  370.     echo "       { [ -s common_name ] && [ -p port] } || { [ -f cert_file ] } || { [ -c certificate file ] }"
  371.     echo ""
  372.     echo "  -a                : Send a warning message through E-mail"
  373.     echo "  -b                : Will not print header"
  374.     echo "  -c cert file      : Print the expiration date for the PEM or PKCS12 formatted certificate in cert file"
  375.     echo "  -e E-mail address : E-mail address to send expiration notices"
  376.     echo "  -f cert file      : File with a list of FQDNs and ports"
  377.     echo "  -h                : Print this screen"
  378.     echo "  -i                : Print the issuer of the certificate"
  379.     echo "  -k password       : PKCS12 file password"
  380.     echo "  -n                : Run as a Nagios plugin"
  381.     echo "  -p port           : Port to connect to (interactive mode)"
  382.     echo "  -s commmon name   : Server to connect to (interactive mode)"
  383.     echo "  -q                : Don't print anything on the console"
  384.     echo "  -v                : Only print validation data"
  385.     echo "  -x days           : Certificate expiration interval (eg. if cert_date < days)"
  386.     echo ""
  387. }
  388.  
  389.  
  390. ##########################################################################
  391. # Purpose: Connect to a server ($1) and port ($2) to see if a certificate
  392. #          has expired
  393. # Arguments:
  394. #   $1 -> Server name
  395. #   $2 -> TCP port to connect to
  396. ##########################################################################
  397. check_server_status() {
  398.  
  399.  
  400.  
  401.     if [ "_${2}" = "_smtp" -o "_${2}" = "_25" ]
  402.     then
  403.         TLSFLAG="-starttls smtp"
  404.  
  405.     elif [ "_${2}" = "_ftp" -o "_${2}" = "_21" ]
  406.     then
  407.         TLSFLAG="-starttls ftp"
  408.  
  409.     elif [ "_${2}" = "_pop3" -o "_${2}" = "_110" ]
  410.     then
  411.         TLSFLAG="-starttls pop3"
  412.    
  413.     elif [ "_${2}" = "_imap" -o "_${2}" = "_143" ]
  414.     then
  415.         TLSFLAG="-starttls imap"
  416.  
  417.     elif [ "_${2}" = "_submission" -o "_${2}" = "_587" ]
  418.     then
  419.         TLSFLAG="-starttls smtp -port ${2}"
  420.     else
  421.         TLSFLAG=""
  422.     fi
  423.  
  424.     echo "" | ${OPENSSL} s_client -connect ${1}:${2} ${TLSFLAG} 2> ${ERROR_TMP} 1> ${CERT_TMP}
  425.  
  426.     if ${GREP} -i  "Connection refused" ${ERROR_TMP} > /dev/null
  427.     then
  428.         prints ${1} ${2} "Connection refused" "Unknown"  
  429.    
  430.     elif ${GREP} -i "gethostbyname failure" ${ERROR_TMP} > /dev/null
  431.     then
  432.         prints ${1} ${2} "Cannot resolve domain" "Unknown"
  433.    
  434.     elif ${GREP} -i "Operation timed out" ${ERROR_TMP} > /dev/null
  435.     then
  436.         prints ${1} ${2} "Operation timed out" "Unknown"  
  437.  
  438.     elif ${GREP} -i "ssl handshake failure" ${ERROR_TMP} > /dev/null
  439.     then
  440.         prints ${1} ${2} "SSL handshake failed" "Unknown"  
  441.  
  442.     elif ${GREP} -i "connect: Connection timed out" ${ERROR_TMP} > /dev/null
  443.     then
  444.         prints ${1} ${2} "Connection timed out" "Unknown"  
  445.  
  446.     else
  447.         check_file_status ${CERT_TMP} $1 $2
  448.     fi
  449. }
  450.  
  451. #####################################################
  452. ### Check the expiration status of a certificate file
  453. ### Accepts three parameters:
  454. ###  $1 -> certificate file to process
  455. ###  $2 -> Server name
  456. ###  $3 -> Port number of certificate
  457. #####################################################
  458. check_file_status() {
  459.  
  460.     CERTFILE=${1}
  461.     HOST=${2}
  462.     PORT=${3}
  463.  
  464.     ### Check to make sure the certificate file exists
  465.     if [ ! -r ${CERTFILE} ] || [ -z ${CERTFILE} ]
  466.     then
  467.         echo "ERROR: The file named ${CERTFILE} is unreadable or doesn't exist"
  468.         echo "ERROR: Please check to make sure the certificate for ${HOST}:${PORT} is valid"
  469.         RETCODE=1
  470.         return
  471.     fi
  472.      
  473.     ### Grab the expiration date from the X.509 certificate
  474.     if [ "${PKCSDBPASSWD}" != "" ]
  475.     then
  476.         # Extract the certificate from the PKCS#12 database, and
  477.         # send the informational message to /dev/null
  478.         ${OPENSSL} pkcs12 -nokeys -in ${CERTFILE} \
  479.                   -out ${CERT_TMP} -password pass:${PKCSDBPASSWD} 2> /dev/null
  480.            
  481.         # Extract the expiration date from the certificate
  482.         CERTDATE=$(${OPENSSL} x509 -in ${CERT_TMP} -enddate -noout | \
  483.                  ${SED} 's/notAfter\=//')
  484.  
  485.         # Extract the issuer from the certificate
  486.         CERTISSUER=$(${OPENSSL} x509 -in ${CERT_TMP} -issuer -noout | \
  487.                     ${AWK} 'BEGIN {RS="/" } $0 ~ /^O=/ \
  488.                                  { print substr($0,3,17)}')
  489.  
  490.         ### Grab the common name (CN) from the X.509 certificate
  491.         COMMONNAME=$(${OPENSSL} x509 -in ${CERT_TMP} -subject -noout | \
  492.                    ${SED} -e 's/.*CN=//' | \
  493.                    ${SED} -e 's/\/.*//')
  494.        
  495.     ### Grab the serial number from the X.509 certificate
  496.         SERIAL=$(${OPENSSL} x509 -in ${CERT_TMP} -serial -noout | \
  497.                    ${SED} -e 's/serial=//')
  498.     else
  499.         # Extract the expiration date from the ceriticate
  500.         CERTDATE=$(${OPENSSL} x509 -in ${CERTFILE} -enddate -noout | \
  501.                  ${SED} 's/notAfter\=//')
  502.  
  503.         # Extract the issuer from the certificate
  504.         CERTISSUER=$(${OPENSSL} x509 -in ${CERTFILE} -issuer -noout | \
  505.                    ${AWK} 'BEGIN {RS="/" } $0 ~ /^O=/ { print substr($0,3,17)}')
  506.  
  507.         ### Grab the common name (CN) from the X.509 certificate
  508.         COMMONNAME=$(${OPENSSL} x509 -in ${CERTFILE} -subject -noout | \
  509.                    ${SED} -e 's/.*CN=//' | \
  510.                    ${SED} -e 's/\/.*//')
  511.     ### Grab the serial number from the X.509 certificate
  512.         SERIAL=$(${OPENSSL} x509 -in ${CERTFILE} -serial -noout | \
  513.                    ${SED} -e 's/serial=//')
  514.     fi
  515.  
  516.     ### Split the result into parameters, and pass the relevant pieces to date2julian
  517.     set -- ${CERTDATE}
  518.     MONTH=$(getmonth ${1})
  519.  
  520.     # Convert the date to seconds, and get the diff between NOW and the expiration date
  521.     CERTJULIAN=$(date2julian ${MONTH#0} ${2#0} ${4})
  522.     CERTDIFF=$(date_diff ${NOWJULIAN} ${CERTJULIAN})
  523.  
  524.     if [ ${CERTDIFF} -lt 0 ]
  525.     then
  526.         if [ "${ALARM}" = "TRUE" ]
  527.         then
  528.             echo "The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" \
  529.                  | ${MAIL} -s "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" has expired!" ${ADMIN}
  530.         fi
  531.  
  532.         prints ${HOST} ${PORT} "Expired" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
  533.         RETCODE=2
  534.  
  535.     elif [ ${CERTDIFF} -lt ${WARNDAYS} ]
  536.     then
  537.         if [ "${ALARM}" = "TRUE" ]
  538.         then
  539.             echo "The SSL certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire on ${CERTDATE}" \
  540.                  | ${MAIL} -s "Certificate for ${HOST} \"(CN: ${COMMONNAME})\" will expire in ${WARNDAYS}-days or less" ${ADMIN}
  541.         fi
  542.         prints ${HOST} ${PORT} "Expiring" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
  543.         RETCODE=1
  544.  
  545.     else
  546.         prints ${HOST} ${PORT} "Valid" "${CERTDATE}" "${CERTDIFF}" "${CERTISSUER}" "${COMMONNAME}" "${SERIAL}"
  547.         RETCODE=0
  548.     fi
  549. }
  550.  
  551. #################################
  552. ### Start of main program
  553. #################################
  554. while getopts abinve:f:c:hk:p:s:qx: option
  555. do
  556.     case "${option}"
  557.     in
  558.         a) ALARM="TRUE";;
  559.         b) NOHEADER="TRUE";;
  560.         c) CERTFILE=${OPTARG};;
  561.         e) ADMIN=${OPTARG};;
  562.         f) SERVERFILE=$OPTARG;;
  563.         h) usage
  564.            exit 1;;
  565.         i) ISSUER="TRUE";;
  566.         k) PKCSDBPASSWD=${OPTARG};;
  567.         n) NAGIOS="TRUE";;
  568.         p) PORT=$OPTARG;;
  569.         s) HOST=$OPTARG;;
  570.         q) QUIET="TRUE";;
  571.         v) VALIDATION="TRUE";;
  572.         x) WARNDAYS=$OPTARG;;
  573.        \?) usage
  574.            exit 1;;
  575.     esac
  576. done
  577.  
  578. if [ -f /usr/bin/mailx ]
  579. then
  580.     MAIL="/usr/bin/mailx"
  581. else
  582.     if [ "${ALARM}" == "FALSE" ]
  583.     then
  584.         MAIL=$(which mail 2>/dev/null)
  585.     else
  586.         MAIL=$(which mail)
  587.     fi
  588. fi
  589.  
  590.  
  591. ### Check to make sure a openssl utility is available
  592. if [ ! -f ${OPENSSL} ]
  593. then
  594.     echo "ERROR: The openssl binary does not exist in ${OPENSSL}."
  595.     echo "FIX: Please modify the \${OPENSSL} variable in the program header."
  596.     exit 1
  597. fi
  598.  
  599. ### Check to make sure a date utility is available
  600. if [ ! -f ${DATE} ]
  601. then
  602.     echo "ERROR: The date binary does not exist in ${DATE} ."
  603.     echo "FIX: Please modify the \${DATE} variable in the program header."
  604.     exit 1
  605. fi
  606.  
  607. ### Check to make sure a grep utility is available
  608. if [ ! -f ${GREP} ]
  609. then
  610.     echo "ERROR: The grep binary does not exist in ${GREP} ."
  611.     echo "FIX: Please modify the \${GREP} variable in the program header."
  612.     exit 1
  613. fi
  614.  
  615. ### Check to make sure the mktemp and printf utilities are available
  616. if [ ! -f ${MKTEMP} ] || [ ! -f ${PRINTF} ]
  617. then
  618.     echo "ERROR: Unable to locate the mktemp or printf binary."
  619.     echo "FIX: Please modify the \${MKTEMP} and \${PRINTF} variables in the program header."
  620.     exit 1
  621. fi
  622.  
  623. ### Check to make sure the sed and awk binaries are available
  624. if [ ! -f ${SED} ] || [ ! -f ${AWK} ]
  625. then
  626.     echo "ERROR: Unable to locate the sed or awk binary."
  627.     echo "FIX: Please modify the \${SED} and \${AWK} variables in the program header."
  628.     exit 1
  629. fi
  630.  
  631. ### CHeck to make sure a mail client is available it automated notifcations are requested
  632. if [ "${ALARM}" = "TRUE" ] && [ ! -f ${MAIL} ]
  633. then
  634.     echo "ERROR: You enabled automated alerts, but the mail binary could not be found."
  635.     echo "FIX: Please modify the ${MAIL} variable in the program header."
  636.     exit 1
  637. fi
  638.  
  639. # Place to stash temporary files
  640. CERT_TMP=$($MKTEMP  /var/tmp/cert.XXXXXX)
  641. ERROR_TMP=$($MKTEMP /var/tmp/error.XXXXXX)
  642.  
  643. ### Baseline the dates so we have something to compare to
  644. MONTH=$(${DATE} "+%m")
  645. DAY=$(${DATE} "+%d")
  646. YEAR=$(${DATE} "+%Y")
  647. NOWJULIAN=$(date2julian ${MONTH#0} ${DAY#0} ${YEAR})
  648.  
  649. ### Touch the files prior to using them
  650. if [ ! -z "${CERT_TMP}" ] && [ ! -z "${ERROR_TMP}" ]
  651. then
  652.     touch ${CERT_TMP} ${ERROR_TMP}
  653. else
  654.     echo "ERROR: Problem creating temporary files"
  655.     echo "FIX: Check that mktemp works on your system"
  656.     exit 1
  657. fi
  658.  
  659. ### If a HOST and PORT were passed on the cmdline, use those values
  660. if [ "${HOST}" != "" ] && [ "${PORT}" != "" ]
  661. then
  662.     print_heading
  663.     check_server_status "${HOST}" "${PORT}"
  664.  
  665. ### If a file is passed to the "-f" option on the command line, check
  666. ### each certificate or server / port combination in the file to see if
  667. ### they are about to expire
  668. elif [ -f "${SERVERFILE}" ]
  669. then
  670.     print_heading
  671.     while read HOST PORT
  672.     do
  673.         if [ "`echo ${HOST} | cut -c1`" = "#" ]
  674.         then
  675.             :
  676.         elif [ "$PORT" = "FILE" ]
  677.         then
  678.             check_file_status ${HOST} "FILE" "${HOST}"
  679.         else
  680.             check_server_status "${HOST}" "${PORT}"
  681.         fi
  682.  
  683.     done < ${SERVERFILE}
  684.  
  685. ### Check to see if the certificate in CERTFILE is about to expire
  686. elif [ "${CERTFILE}" != "" ]
  687. then
  688.     print_heading
  689.     check_file_status ${CERTFILE} "FILE"  "${CERTFILE}"
  690.  
  691. ### There was an error, so print a detailed usage message and exit
  692. else
  693.     usage
  694.     exit 1
  695. fi
  696.  
  697. ### Remove the temporary files
  698. rm -f ${CERT_TMP} ${ERROR_TMP}
  699.  
  700. ### Exit with a success indicator
  701. if [ "${NAGIOS}" = "TRUE" ]; then
  702.     exit $RETCODE
  703. else
  704.     exit 0
  705. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement