@@ -55,7 +55,7 @@ SCRIPT_SOURCE_URL="${LOCAL_HTTPS_SOURCE_URL:-$SCRIPT_SOURCE_URL_DEFAULT}"
5555# Friendly domain name added to the certificate SANs (and used as the preferred
5656# URL when Pi-hole is present). Configurable so it does not have to be "pi.hole".
5757# Precedence at runtime:
58- # LOCAL_HTTPS_DOMAIN env > --domain CLI > persisted state > Pi-hole webserver.domain > default.
58+ # --domain CLI > LOCAL_HTTPS_DOMAIN env > persisted state > Pi-hole webserver.domain > default.
5959DOMAIN_DEFAULT=" pi.hole"
6060DOMAIN=" "
6161DOMAIN_CLI=" "
@@ -151,15 +151,39 @@ read_state_value() {
151151
152152sanitize_domain () {
153153 local d=" ${1:- } "
154- d=" $( printf ' %s' " $d " | tr -d ' [:space:]' | tr ' A-Z' ' a-z' ) "
155- d=" ${d# .} "
154+ d=" $( printf ' %s' " $d " | sed ' s/^[[:space:]]*//;s/[[:space:]]*$//' | tr ' A-Z' ' a-z' ) "
156155 d=" ${d% .} "
156+
157+ [ -n " $d " ] || { printf ' %s' " " ; return 0; }
158+ [ " ${# d} " -le 253 ] || { printf ' %s' " " ; return 0; }
159+
157160 case " $d " in
158- " " | * [!a-z0-9.-]* ) printf ' %s' " " ; return 0 ;;
161+ * [!a-z0-9.-]* |. * | * .. * | * - ) printf ' %s' " " ; return 0 ;;
159162 esac
163+
164+ if [[ " $d " =~ ^([0-9]{1,3}\. ){3}[0-9]{1,3}$ ]]; then
165+ printf ' %s' " "
166+ return 0
167+ fi
168+
169+ local label=" "
170+ local labels=()
171+ IFS=' .' read -r -a labels <<< " $d"
172+ for label in " ${labels[@]} " ; do
173+ [ -n " $label " ] || { printf ' %s' " " ; return 0; }
174+ [ " ${# label} " -le 63 ] || { printf ' %s' " " ; return 0; }
175+ case " $label " in
176+ -* |* -|* [!a-z0-9-]* ) printf ' %s' " " ; return 0 ;;
177+ esac
178+ done
179+
160180 printf ' %s' " $d "
161181}
162182
183+ domain_error () {
184+ die " Invalid domain: $1 . Use a DNS name like pi.hole, home.lan, or dns.home. Labels must start and end with a letter or digit."
185+ }
186+
163187detect_pihole_domain () {
164188 local d=" "
165189
@@ -187,21 +211,30 @@ detect_pihole_domain() {
187211
188212resolve_domain () {
189213 local d=" "
214+ local clean=" "
190215 DOMAIN_FROM_PIHOLE=0
191- if [ -n " ${LOCAL_HTTPS_DOMAIN:- } " ]; then
192- d=" $LOCAL_HTTPS_DOMAIN "
193- elif [ -n " ${DOMAIN_CLI:- } " ]; then
194- d=" $DOMAIN_CLI "
216+
217+ if [ -n " ${DOMAIN_CLI:- } " ]; then
218+ clean=" $( sanitize_domain " $DOMAIN_CLI " ) "
219+ [ -n " $clean " ] || domain_error " $DOMAIN_CLI "
220+ d=" $clean "
221+ elif [ -n " ${LOCAL_HTTPS_DOMAIN:- } " ]; then
222+ clean=" $( sanitize_domain " $LOCAL_HTTPS_DOMAIN " ) "
223+ [ -n " $clean " ] || domain_error " $LOCAL_HTTPS_DOMAIN "
224+ d=" $clean "
195225 else
196226 d=" $( read_state_value domain) "
227+ clean=" $( sanitize_domain " $d " ) "
228+ d=" $clean "
197229 if [ -z " $d " ] && [ " ${PIHOLE_PRESENT:- 0} " -eq 1 ]; then
198- d=" $( sanitize_domain " $( detect_pihole_domain) " ) "
199- if [ -n " $d " ]; then
230+ clean=" $( sanitize_domain " $( detect_pihole_domain) " ) "
231+ if [ -n " $clean " ]; then
232+ d=" $clean "
200233 DOMAIN_FROM_PIHOLE=1
201234 fi
202235 fi
203236 fi
204- d= " $( sanitize_domain " $d " ) "
237+
205238 [ -n " $d " ] || d=" $DOMAIN_DEFAULT "
206239 DOMAIN=" $d "
207240}
@@ -589,7 +622,7 @@ print_help() {
589622 echo " - If already installed, --install will not run again."
590623 echo " - Reinstall only via: --uninstall then --install"
591624 echo " - --domain sets the friendly name added to the certificate (default: $DOMAIN_DEFAULT )."
592- echo " It is remembered across renewals. You can also set LOCAL_HTTPS_DOMAIN ."
625+ echo " It overrides LOCAL_HTTPS_DOMAIN and is remembered across renewals."
593626 echo " If Pi-hole is detected and no domain is set, its webserver.domain is used."
594627 echo " "
595628}
@@ -2204,8 +2237,18 @@ parse_cli() {
22042237 shift
22052238 while [ " $# " -gt 0 ]; do
22062239 case " $1 " in
2207- --domain) DOMAIN_CLI=" ${2:- } " ; shift 2 || shift ; continue ;;
2208- --domain=* ) DOMAIN_CLI=" ${1#* =} " ;;
2240+ --domain)
2241+ [ " $# " -ge 2 ] || die " Missing value for --domain. Use: --domain <name>"
2242+ [ -n " ${2:- } " ] || die " Missing value for --domain. Use: --domain <name>"
2243+ case " $2 " in --* ) die " Missing value for --domain. Use: --domain <name>" ;; esac
2244+ DOMAIN_CLI=" $2 "
2245+ shift 2
2246+ continue
2247+ ;;
2248+ --domain=* )
2249+ DOMAIN_CLI=" ${1#* =} "
2250+ [ -n " $DOMAIN_CLI " ] || die " Missing value for --domain. Use: --domain <name>"
2251+ ;;
22092252 * ) ;;
22102253 esac
22112254 shift
@@ -2218,8 +2261,18 @@ parse_cli() {
22182261 while [ " $# " -gt 0 ]; do
22192262 case " $1 " in
22202263 --force-renew) FORCE_RENEW=1 ;;
2221- --domain) DOMAIN_CLI=" ${2:- } " ; shift 2 || shift ; continue ;;
2222- --domain=* ) DOMAIN_CLI=" ${1#* =} " ;;
2264+ --domain)
2265+ [ " $# " -ge 2 ] || die " Missing value for --domain. Use: --domain <name>"
2266+ [ -n " ${2:- } " ] || die " Missing value for --domain. Use: --domain <name>"
2267+ case " $2 " in --* ) die " Missing value for --domain. Use: --domain <name>" ;; esac
2268+ DOMAIN_CLI=" $2 "
2269+ shift 2
2270+ continue
2271+ ;;
2272+ --domain=* )
2273+ DOMAIN_CLI=" ${1#* =} "
2274+ [ -n " $DOMAIN_CLI " ] || die " Missing value for --domain. Use: --domain <name>"
2275+ ;;
22232276 * ) ;;
22242277 esac
22252278 shift
@@ -2251,8 +2304,18 @@ parse_cli() {
22512304 shift
22522305 while [ " $# " -gt 0 ]; do
22532306 case " $1 " in
2254- --domain) DOMAIN_CLI=" ${2:- } " ; shift 2 || shift ; continue ;;
2255- --domain=* ) DOMAIN_CLI=" ${1#* =} " ;;
2307+ --domain)
2308+ [ " $# " -ge 2 ] || die " Missing value for --domain. Use: --domain <name>"
2309+ [ -n " ${2:- } " ] || die " Missing value for --domain. Use: --domain <name>"
2310+ case " $2 " in --* ) die " Missing value for --domain. Use: --domain <name>" ;; esac
2311+ DOMAIN_CLI=" $2 "
2312+ shift 2
2313+ continue
2314+ ;;
2315+ --domain=* )
2316+ DOMAIN_CLI=" ${1#* =} "
2317+ [ -n " $DOMAIN_CLI " ] || die " Missing value for --domain. Use: --domain <name>"
2318+ ;;
22562319 * ) ;;
22572320 esac
22582321 shift
0 commit comments