#!/bin/sh # # Purpose {{{ # This script will display SSL dates of a given URL # 1. … # … # # 2021-12-06 # }}} # Vars {{{ readonly PROGNAME=$(basename "${0}") readonly PROGDIR=$(readlink -m $(dirname "${0}")) readonly ARGS="${*}" readonly NBARGS="${#}" [ -z "${DEBUG}" ] && DEBUG=1 ## Export DEBUG for sub-script export DEBUG # Default values for some vars readonly MY_VAR_XY_DEFAULT="666" ## Colors readonly PURPLE='\033[1;35m' readonly RED='\033[0;31m' readonly RESET='\033[0m' readonly COLOR_DEBUG="${PURPLE}" # }}} usage() { # {{{ cat <<- EOF usage: $PROGNAME [-d|-h] -f /urls/list/path|-u URL Try to get SSL's date (notBefore and notAfter) from URL(s). EXAMPLES : - Get dates for wikipedia.org's SSL cert ${PROGNAME} --url wikipedia.org - Get SSL dates for all URLs of the given file ${PROGNAME} --file /tmp/ssl.url.list OPTIONS : -d,--debug Enable debug messages. -f,--file Specify the file with URLs to verify. -h,--help Print this help message. -u,--url Specify the URL to verify. EOF } # }}} debug_message() { # {{{ local_message="${1}" ## Print message if DEBUG is enable (=0) [ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_message}" return 0 } # }}} error_message() { # {{{ local_error_message="${1}" local_error_code="${2}" ## Print message if DEBUG is enable (=0) [ "${DEBUG}" -eq "0" ] && printf '%b\n' "ERROR − ${PROGNAME} : ${RED}${local_error_message}${RESET}" exit "${local_error_code:=66}" } # }}} define_vars() { # {{{ ## If my_var_xy wasn't defined (argument) {{{ if [ -z "${my_var_xy}" ]; then ## Use default value readonly my_var_xy="${MY_VAR_XY_DEFAULT}" fi ## }}} } # }}} is_var_defined() { # {{{ local_var_defined="${1}" ## Return an error by default return_is_var_defined="1" ## If the length of the variable is nonzero if [ -n "${local_var_defined}" ]; then debug_message "is_var_defined − \ Variable ${RED}is defined${COLOR_DEBUG} and not empty." return_is_var_defined="0" else debug_message "is_var_defined − \ Var is ${RED}not${COLOR_DEBUG} defined or empty." return_is_var_defined="1" fi return "${return_is_var_defined}" } # }}} is_file_present() { # {{{ local_file_present="${1}" ## File doesn't exist by default return_is_file_present="1" ### Check if the file exists # shellcheck disable=SC2086 if find ${local_file_present} > /dev/null 2>&1; then return_is_file_present="0" debug_message "is_file_present − \ The file ${RED}${local_file_present}${COLOR_DEBUG} exists." else return_is_file_present="1" debug_message "is_file_present − \ The file ${RED}${local_file_present}${COLOR_DEBUG} doesn't exist." fi return "${return_is_file_present}" } # }}} display_url_date() { # {{{ local_ssl_url="${1}" ## Return an error by default return_display_url_date="1" if echo | openssl s_client -servername "${local_ssl_url}" -connect "${local_ssl_url}":443 2>/dev/null \ | openssl x509 > /dev/null 2>&1 ; then debug_message "display_url_date − \ Successfully got SSL's dates from ${RED}${local_ssl_url}${COLOR_DEBUG} URL." ### Display SSL's dates echo | openssl s_client -servername "${local_ssl_url}" -connect "${local_ssl_url}":443 2>/dev/null | openssl x509 -noout -dates return_display_url_date="0" else debug_message "display_url_date − \ Error with 'openssl' command for ${RED}${local_ssl_url}${COLOR_DEBUG}." return_display_url_date="1" fi return "${return_display_url_date}" } # }}} main() { # {{{ ## If script should not be executed right now {{{ ### Exit #is_script_ok \ #&& exit 0 ## }}} ## Define all vars define_vars ## If an URL was given as argument {{{ ### Display the URL ### AND Try to get SSL's dates ### AND exit is_var_defined "${ssl_url}" \ && printf '%b\n' "Try to get SSL dates for ${RED}${ssl_url}${RESET} URL :" \ && display_url_date "${ssl_url}" \ && exit 0 ## }}} ## If a file was given as argument {{{ ### Display the URL ### AND Try to get SSL's dates ### AND exit is_var_defined "${ssl_url_list_path}" \ && is_file_present "${ssl_url_list_path}" \ && printf '%b\n' "Try to manage URLs from ${RED}${ssl_url_list_path}${RESET} file :" \ && while IFS= read -r url; do printf '%b\n' "Try to get SSL dates for ${RED}${url}${RESET} URL :" display_url_date "${url}" done < "${ssl_url_list_path}" \ && exit 0 ## }}} ## Display help message {{{ ### AND exit with error usage \ && error_message "Please use at least -f or -u argument to give a file or an URL. See help message." 1 ## }}} } # }}} # Manage arguments # {{{ # This code can't be in a function due to argument management if [ ! "${NBARGS}" -eq "0" ]; then manage_arg="0" ## If the first argument is not an option if ! printf -- '%s' "${1}" | grep -q -E -- "^-+"; then ## Print help message and exit printf '%b\n' "${RED}Invalid option: ${1}${RESET}" printf '%b\n' "---" usage exit 1 fi # Parse all options (start with a "-") one by one while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do case "${1}" in -d|--debug ) ## debug DEBUG=0 ;; -h|--help ) ## help usage ## Exit after help informations exit 0 ;; -f|--file ) ## Define ssl_url_list_path with given arg ## Move to the next argument shift ## Define var readonly ssl_url_list_path="${1}" ;; -u|--url ) ## Define ssl_url with given arg ## Move to the next argument shift ## Define var readonly ssl_url="${1}" ;; * ) ## unknow option printf '%b\n' "${RED}Invalid option: ${1}${RESET}" printf '%b\n' "---" usage exit 1 ;; esac debug_message "Arguments management − \ ${RED}${1}${COLOR_DEBUG} option managed." ## Move to the next argument shift manage_arg=$((manage_arg+1)) done debug_message "Arguments management − \ ${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed." else debug_message "Arguments management − \ No arguments/options to manage." fi # }}} main exit 255