[GTALUG] Script to show HTTP(S) and TLS details for a website

Giles Orr gilesorr at gmail.com
Mon Aug 12 09:07:57 EDT 2019


Well damn.  That's a lot of very good suggestions.

I will dispute one of them: you said (more than once I think) that I don't
need to quote variables.  You are technically correct ... right up until a
variable value has a space in it.  Then everything goes to hell in a
handbasket.  I use 'shellcheck' ( https://github.com/koalaman/shellcheck )
through NeoVim's Syntastic ( https://github.com/vim-syntastic/syntastic )
plugin, and it's a real nag about quoting variables.  And I agree with it,
having had unquoted variables explode in my face.

I hope to implement and test most of the rest of your suggestions (along
with the previous ones) shortly.  Thanks.


On Sun, 11 Aug 2019 at 23:49, William Park via talk <talk at gtalug.org> wrote:

> On Sat, Aug 10, 2019 at 11:46:40AM -0400, Giles Orr via talk wrote:
> > If you're interested, you can find the details here:
> >
> > https://www.gilesorr.com/blog/tls-https-details.html
> >
> > Any suggestions to improve the script would be most welcome.
>
> OK, here it goes...
>
> > # Put most desirable/least-likely last:
> > for opensslbinary in /usr/local/opt/openssl at 1.1/bin/openssl
> /usr/local/opt/opens
> > sl/bin/openssl /usr/bin/openssl
> > do
> >     # Every version of OpenSSL I've checked (several across multiple
> >     # OpenSSL versions and Apple's LibreSSL) respond to 'openssl version'
> >     # with '<brand> <version-no> ...' - there may or may not be stuff
> after
> >     # those two items (usually a build date, but not with Libre).
> >     #
> >     if [ -f "${opensslbinary}" ]
>
> '-f' tests if it's a file.  Maybe you should use '-x' which tests if it's
> executable.
>
> >     then
> >         output="$("${opensslbinary}" version)"
> >         brand="$(  echo "${output}" | awk '{ print $1 }')"
> >         version="$(echo "${output}" | awk '{ print $2 }')"
> >         if [[ "OpenSSL" == "${brand}" ]]
> >         then
> >             if [[ "${version}" == "1.1"* ]]
> >             then
> >                 OPENSSL="${opensslbinary}"
> >             fi
> >         fi
>
> You got 7 subshells here.  You can reduce it to 1 subshell:
>
>         read a b rest <<< $($opensslbinary version)
>         case $a:$b in
>             OpenSSL:1.1*) OPENSSL=$opensslbinary ;;
>         esac
>
> >     fi
> > done
>
> Maybe you should break out of the for-loop as soon as you find something
> correct.  As is, OPENSSL will be the last correct one.
>
>
> > function help() {
> >     echo "Usage:"
> >     echo "    $(basename "${0}") [-h]|<domain-name>"
> >     echo ""
> >     echo "Show HTTP(s) and certificate details."
> >     echo "Do not include the 'http(s)://' leader on the domain name."
> >     echo ""
> >     echo "-h            show this help and exit"
>
> Instead of echo'ing each and every line, you can do
>
>     cat << EOF
> Usage:
>     $(basename "${0}") [-h]|<domain-name>
>
> Show HTTP(s) and certificate details.
> Do not include the 'http(s)://' leader on the domain name.
>
> -h            show this help and exit
> EOF
>
>
> > function expiry_date() {
> >     echo "${1}" | ${OPENSSL} x509 -noout -dates | grep notAfter | awk
> 'BEGIN { F
> > S="=" } { print $2 }'
> > }
>
> You can get rid of grep, since you're already using awk.
>
>     echo "$1" | ${OPENSSL} x509 -noout -dates | awk -F= '/notAfter/ {print
> $2}'
>
> >
> > function days_to_expiry() {
> >     expiry_date="$(echo "${1}" | ${OPENSSL} x509 -noout -dates | grep
> notAfter |
> >  awk 'BEGIN { FS="=" } { print $2 }')"
>
> You already defined expiry_date(), so why not use it here.
>
>     expiry_date=$(expiry_date "$1")
>
> >     if [[ "$(date --version 2>/dev/null)" == *"GNU"* ]]
> >     then
> >         # Linux (or at least GNU)
> >         expiry_epoch_seconds=$(date --date="${expiry_date}" "+%s")
> >     else
> >         # Assuming the Mac version:
> >         expiry_epoch_seconds=$(date -jf '%b %e %H:%M:%S %Y %Z'
> "${expiry_date}"
> > "+%s")
> >     fi
>
> Testing for "GNU" string can be done more simply using grep.
>
>     if date --version 2>/dev/null | grep -q GNU; then
>         ...
>     else
>         ...
>     fi
>
> > function tlsversions() {
> >     successful=""
> >     failed=""
> >     for tlsversion in ssl2 ssl3 tls1 tls1_1 tls1_2 tls1_3
> >     do
> >         success=$(echo | ${OPENSSL} s_client -connect "${1}":443
> -${tlsversion}
> > > /dev/null 2> /dev/null ; echo $?)
> >         if [ ${success} -eq 0 ]
> >         then
> >             successful="${tlsversion} ${successful}"
> >         else
> >             failed="${tlsversion} ${failed}"
> >         fi
>
> Testing if a command succeeded or failed can be done in-line.
>
>         if echo | ${OPENSSL} s_client -connect "${1}":443 -${tlsversion}
> &>/dev/null; then
>             successful=...
>         else
>             failed=...
>         fi
>
> Also, do you really need to send empty line to openssl?  Maybe you can
> redirect
> stdin from /dev/null as well, like
>
>     openssl ... </dev/null ...
>
> That will reduce 3 subshells to 0.
>
>
> General observation:
>
> 1. You don't need quotes in variable assignments like
>         var="$(...)"
>         var="$var1"
>
> 2. The following tests are the same.  They both tests if var is empty.
>         [ "$var"x = x ]
>         [ -z "$var" ]
>
> 3. Testing if command succeeded or failed can be done in-line.
>         if command1 | command2 | command2; then
>             ...
>         else
>             ...
>         fi
>
> 4. Case statement is usually better than if statement.  eg.
>         if [[ "$var" == glob ]]; then
>             ...
>         fi
>    vs
>         case $var in
>             glob) ... ;;
>         esac
>     Note the missing quotes in case, too.  You don't need it.
> --
> William Park <opengeometry at yahoo.ca>
> ---
> Post to this mailing list talk at gtalug.org
> Unsubscribe from this mailing list
> https://gtalug.org/mailman/listinfo/talk
>


-- 
Giles
https://www.gilesorr.com/
gilesorr at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://gtalug.org/pipermail/talk/attachments/20190812/a7121f82/attachment.html>


More information about the talk mailing list