From e6825a9a221709bbdc4c224b746fc62881f56739 Mon Sep 17 00:00:00 2001 From: B Stack Date: Thu, 16 Aug 2018 11:54:17 -0400 Subject: update error checking and exit codes Removing the final double-quote from the regular expression in the DISPOSITION check enables us to capture more interesting error messages from the server, including the "Denied" message when you request an incorrectly-named cert template. Performed major rewrite of exit codes, to fix issue #2. --- files/certreq.sh | 67 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 29 deletions(-) (limited to 'files/certreq.sh') diff --git a/files/certreq.sh b/files/certreq.sh index 2aa27f8..5a21205 100755 --- a/files/certreq.sh +++ b/files/certreq.sh @@ -12,13 +12,14 @@ # 2018-05-07 Add actions for using a CA with manually-approved certs # 2018-06-19 Fix get number of ca cert # 2018-07-30 add error checking on the request and authorization +# 2018-08-16 update error checking and exit codes # Usage: in ansible role certreq # Microsoft CA cert templates have permissions on them. A user must be able to "enroll" on the template. # Reference: ftemplate.sh 2017-10-10x; framework.sh 2017-10-09a # fundamental curl statements https://stackoverflow.com/questions/31283476/submitting-base64-csr-to-a-microsoft-ca-via-curl/39722983#39722983 # Improve: fiversion="2017-10-10x" -certreqversion="2018-07-30a" +certreqversion="2018-08-16a" usage() { less -F >&2 <401.*" | grep -oiE ">.*<" | tr -d '<>' )" MESSAGE="${MESSAGE:-${DISPOSITION}}" # use disposition if message is not available @@ -164,7 +161,7 @@ submit_csr() { fetch_signed_cert() { # call: fetch_signed_cert "${CERTREQ_USER}:${CERTREQ_PASS}" "${CERTREQ_CA}" "${CERTREQ_CAHOST}" "${CERTLINK}" "${CERTREQ_CNPARAM}" "${CERTREQ_ACTION}" "${CERTREQ_REQID}" # output: - # vars: ${finaloutput} + # vars: ${curloutput} # files: ${CERTREQ_WORKDIR}/${this_filename}.crt debuglev 9 && ferror "$FUNCNAME $@" @@ -199,7 +196,7 @@ fetch_signed_cert() { -H "Referer: ${this_ca}/certsrv/certrqxt.asp" \ -H 'User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko' \ -H 'Content-Type: application/x-www-form-urlencoded' > "${CERTREQ_WORKDIR}/${this_filename}.crt" - finaloutput=$? + curloutput=$? } @@ -253,7 +250,7 @@ get_latest_ca_cert_chain() { # RENAME TO PROPER FILENAME # will read only the first cert, so get domain of issuer of it. - CA_DOMAIN="$( openssl x509 -in "${CERTREQ_TEMPFILE}" -noout -issuer 2>&1 | sed -r -e 's/^.*CN=[A-Za-z0-9]+\.//;' )" + CA_DOMAIN="$( openssl x509 -in "${CERTREQ_TEMPFILE}" -noout -issuer 2>/dev/null | sed -r -e 's/^.*CN=[A-Za-z0-9]+\.//;' )" CHAIN_FILE="chain-${CA_DOMAIN}.crt" mv -f "${CERTREQ_TEMPFILE}" "${CERTREQ_WORKDIR}/${CHAIN_FILE}" 1>/dev/null 2>&1 @@ -262,7 +259,7 @@ get_latest_ca_cert_chain() { action_get_cert() { # call: action_get_cert "${CERTREQ_CNPARAM}" "${CERTREQ_SUBJECT}" "${CERTREQ_USER}:${CERTREQ_PASS}" "${CERTREQ_CA}" "${CERTREQ_CAHOST}" "${CERTREQ_ACTION}" "${CERTREQ_CSR}" # outputs: - # vars: ${finaloutput} + # vars: ${curloutput} # files: ${CHAIN_FILE} ${CERTREQ_CNPARAM}.crt and .key and debuglev 9 && ferror "$FUNCNAME $@" @@ -295,7 +292,7 @@ action_get_cert() { # FETCH SIGNED CERTIFICATE fetch_signed_cert "${this_user_string}" "${this_ca}" "${this_ca_host}" "${CERTLINK}" "${this_cnparam}" "${this_action}" "REQID-not-needed-for-this-action" debuglev 8 && { - echo "finaloutput=${finaloutput}" + echo "curloutput=${curloutput}" } if ! fistruthy "${CERTREQ_SKIP_CACERTS}" ; @@ -362,7 +359,7 @@ action_fetch() { fetch_signed_cert "${this_user_string}" "${this_ca}" "${this_ca_host}" "WILL-BE-REPLACED" "${this_cnparam}" "${this_action}" "${this_reqid}" debuglev 8 && { - echo "finaloutput=${finaloutput}" + echo "curloutput=${curloutput}" } if ! fistruthy "${CERTREQ_SKIP_CACERTS}" ; @@ -626,21 +623,32 @@ debuglev 5 && { # default action="generate" # also catches "generate-csr" action_get_cert "${CERTREQ_CNPARAM}" "${CERTREQ_SUBJECT}" "${CERTREQ_USER}:${CERTREQ_PASS}" "${CERTREQ_CA}" "${CERTREQ_CAHOST}" "${CERTREQ_ACTION}" "${CERTREQ_CSR}" - - # CHECK EVERYTHING - failed=0 - openssloutput="$( openssl x509 -in "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" -noout -subject -issuer -startdate -enddate 2>/dev/null )" - grep -qE -- 'REQUEST--' "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" && failed=$(( failed + 1 )) - grep -qiE '\<\/?body\>' "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" && failed=$(( failed + 2 )) - test ${finaloutput} -ne 0 && failed=$(( failed + 4 )) - grep -qE -- '--END CERTIFICATE--' "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" || failed=$(( failed + 8 )) - #echo "${openssloutput}" | grep -qE "subject.*${CERTREQ_SUBJECT}" || failed=$(( failed + 16 )) - echo "${openssloutput}" | grep -qE "issuer.*" || failed=$(( failed + 16 )) - echo "${MESSAGE}" | grep -qiE 'policy' && failed=$(( failed + 32 )) - echo "${MESSAGE}" | grep -qiE 'unauthorized' && failed=$(( failed + 64 )) ;; + esac + # CHECK EVERYTHING + failed=0 # start out with everything worked + openssloutput="$( openssl x509 -in "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" -noout -subject -issuer -startdate -enddate 2>/dev/null )" + + # 1 interaction with website failed: invalid login credentials or curl returned non-zero value + if echo "${MESSAGE}" | grep -qiE 'unauthorized' || test ${curloutput} -ne 0 ; + then + failed=$(( failed + 1 )) + fi + + # 2 cert request denied + if echo "${MESSAGE}" | grep -qiE 'policy' ; + then + failed=$(( failed + 2 )) + fi + + # 4 invalid cert file: incomplete cert file, or no issuer + if { ! grep -qE -- '--END CERTIFICATE--' "${CERTREQ_WORKDIR}/${CERTREQ_CNPARAM}.crt" ; } || { ! echo "${openssloutput}" | grep -qE "issuer.*" ; } ; + then + failed=$(( failed + 4 )) + fi + } 1> ${logfile} 2>&1 case "${CERTREQ_ACTION}" in @@ -678,13 +686,14 @@ case "${CERTREQ_ACTION}" in ! fistruthy "${CERTREQ_SKIP_CACERTS}" && echo "chain: ${CERTREQ_WORKDIR}/${CHAIN_FILE}" echo "message: ${MESSAGE}" echo "rc: ${failed}" - ;; esac clean_certreq -exit "${failed:-0}" + +exit_code() { return "${1:-0}" ; } +exit_code "${failed:-0}" # EMAIL LOGFILE #${sendsh} ${sendopts} "${server} ${scriptfile} out" ${logfile} ${interestedparties} -- cgit