From 26f20c5890b84efec8301ccc1983e35158d405f1 Mon Sep 17 00:00:00 2001 From: Timothe Litt Date: Sun, 24 Mar 2024 20:07:03 -0400 Subject: [PATCH] Use /etc/services (or local equivalent" to translate port names. SERVER_TYPE implies a port number (and possibly s_client options). Previously, these were hard-coded, requiring a code change for any new/unique services. Now, /etc/services is used, so every assigned name is available, and new services "just work". The old alias names (and renames) are supported. And the old hardcoded defaults will be used if /etc/services is not available. SERVICES_FILE can be defined to local taste - e.g. on windows, C:\Windows\System32\drivers\etc\services is equivalent. --- getssl | 98 ++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/getssl b/getssl index a30250b..765961f 100755 --- a/getssl +++ b/getssl @@ -299,6 +299,7 @@ # 2024-03-21 Ensure that --all doesn't run --new-account-key or --DEACTIVATE-account more than once. (tlhackque) # 2024-03-21 Avoid domain processing when the action is account management. (tlhackque) # 2024-03-24 Implement multiple ACCOUNT_EMAIL addresses (tlhackque) +# 2024-03-24 Use /etc/services (or similar) to translate port names. (tlhackque) # ---------------------------------------------------------------------------------------- case :$SHELLOPTS: in @@ -2489,44 +2490,67 @@ requires() { # check if required function is available fi } +# Find remote port number and any special connect commands (e.g. starttls) +# Consults /etc/services (or whatever SERVICES_FILE is set to) if available. +# Aliases name to (sometimes weird) conventions used by previous versions +# of getssl. If /etc/services is available, ALL registered port names can +# be used. No new aliases should be created. Add extra_cmds as/if openssl +# provides STARTTLS support of other needs arise. true if success, false on fail. + +function find_service_port() { + local name="$1" line + # "extra" commands from IANA port number + local extra_cmds=([21]="-starttls ftp" [143]="-starttls imap" [110]="-starttls pop3" + [25]="-starttls smtp" [587]="-starttls smtp" [5222]="-starttls xmpp" + [5432]="-starttls postgres") + # Standard name IANA-assigned name from previous conventions + declare -A aliases=(["webserver"]="https" ["ftpi"]="ftps" ["smtps_deprecated"]="smtps" + ["smtps"]="submission" ["smtp_submission"]="submission" ["xmpp"]="xmpp-client" + ["xmpps"]="xmpp-server") + # Fallback name => port mapping (what previous code did) + declare -A defaults=(["https"]=443 ["ftp"]=21 ["ftps"]=990 ["imap"]=143 ["imaps"]=993 + ["pop3"]=110 ["pop3s"]=995 ["smtp"]=25 ["smtps"]=465 ["submission"]=587 + ["xmpp-client"]=5222 ["xmpp-server"]=5369 ["ldaps"]=636 ["postgres"]=5432) + + # Numeric name => just check for extras + if [[ "$name" =~ ^([0-9]+)$ ]]; then + _PORT="$name" + _EXTRA="${extra_cmds[$_PORT]}" + return 0 + fi + + # If customized non-IANA aliase, convert to IANA (standard) name + [ -n "${aliases["$name"]}" ] && name="${aliases["$name"]}" + + # Default and search the SERVICES_FILE. (Grep does a preliminary match for speed.) + [ -z "$SERVICES_FILE" ] && SERVICES_FILE="/etc/services" + _PORT= + _EXTRA= + if [ -r "$SERVICES_FILE" ]; then + while read -r "line" ; do + line="$(tr -s ' \t' ' ' <<<"${line/\#*/}")" + [[ "$line" =~ ^\ *$ ]] && continue + if [[ "$line" =~ ^"$name "([[:digit:]]+)[/,]tcp(\ |$) ]] || + [[ "$line" =~ ^[a-zA-Z0-9_-]+\ ([[:digit:]]+)[/,]tcp.*" $name"(\ |$) ]]; then + _PORT="${BASH_REMATCH[1]}" + _EXTRA="${extra_cmds[$_PORT]}" + return 0 + fi + done <<<"$(grep "$name" "$SERVICES_FILE")" + fi + + # No file or no match, try fallback defaults. + + _PORT="${defaults[$name]}" + [ -z "$_PORT" ] && return 1 + _EXTRA="${extra_cmds[$_PORT]}" + return 0 +} + set_server_type() { # uses SERVER_TYPE to set REMOTE_PORT and REMOTE_EXTRA - if [[ ${SERVER_TYPE} == "https" ]] || [[ ${SERVER_TYPE} == "webserver" ]]; then - REMOTE_PORT=443 - elif [[ ${SERVER_TYPE} == "ftp" ]]; then - REMOTE_PORT=21 - REMOTE_EXTRA="-starttls ftp" - elif [[ ${SERVER_TYPE} == "ftpi" ]]; then - REMOTE_PORT=990 - elif [[ ${SERVER_TYPE} == "imap" ]]; then - REMOTE_PORT=143 - REMOTE_EXTRA="-starttls imap" - elif [[ ${SERVER_TYPE} == "imaps" ]]; then - REMOTE_PORT=993 - elif [[ ${SERVER_TYPE} == "pop3" ]]; then - REMOTE_PORT=110 - REMOTE_EXTRA="-starttls pop3" - elif [[ ${SERVER_TYPE} == "pop3s" ]]; then - REMOTE_PORT=995 - elif [[ ${SERVER_TYPE} == "smtp" ]]; then - REMOTE_PORT=25 - REMOTE_EXTRA="-starttls smtp" - elif [[ ${SERVER_TYPE} == "smtps_deprecated" ]]; then - REMOTE_PORT=465 - elif [[ ${SERVER_TYPE} == "smtps" ]] || [[ ${SERVER_TYPE} == "smtp_submission" ]]; then - REMOTE_PORT=587 - REMOTE_EXTRA="-starttls smtp" - elif [[ ${SERVER_TYPE} == "xmpp" ]]; then - REMOTE_PORT=5222 - REMOTE_EXTRA="-starttls xmpp" - elif [[ ${SERVER_TYPE} == "xmpps" ]]; then - REMOTE_PORT=5269 - elif [[ ${SERVER_TYPE} == "ldaps" ]]; then - REMOTE_PORT=636 - elif [[ ${SERVER_TYPE} == "postgres" ]]; then - REMOTE_PORT=5432 - REMOTE_EXTRA="-starttls postgres" - elif [[ ${SERVER_TYPE} =~ ^[0-9]+$ ]]; then - REMOTE_PORT=${SERVER_TYPE} + if find_service_port "$SERVER_TYPE" ; then + REMOTE_PORT="$_PORT" + REMOTE_EXTRA="$_EXTRA" else info "${DOMAIN}: unknown server type \"$SERVER_TYPE\" in SERVER_TYPE" config_errors=true