From: Konstantin Demin Date: Tue, 9 Jan 2024 00:40:02 +0000 (+0300) Subject: dropbear: adjust file permissions X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=05100d865158a5d6eaf8b34a8deb0d447cc73301;p=openwrt%2Fstaging%2Flinusw.git dropbear: adjust file permissions runtime: - adjust ownership/permissions while starting dropbear build time: - correct file permissions for preseed files in $(TOPDIR)/files/etc/dropbear/ (if any) closes #10849 Signed-off-by: Konstantin Demin --- diff --git a/package/network/services/dropbear/Makefile b/package/network/services/dropbear/Makefile index c00f64006e..2d7ce75b8d 100644 --- a/package/network/services/dropbear/Makefile +++ b/package/network/services/dropbear/Makefile @@ -70,10 +70,11 @@ define Package/dropbear/description endef define Package/dropbear/conffiles -$(if $(CONFIG_DROPBEAR_ED25519),/etc/dropbear/dropbear_ed25519_host_key) -$(if $(CONFIG_DROPBEAR_ECC),/etc/dropbear/dropbear_ecdsa_host_key) -/etc/dropbear/dropbear_rsa_host_key /etc/config/dropbear +/etc/dropbear/authorized_keys +/etc/dropbear/dropbear_ecdsa_host_key +/etc/dropbear/dropbear_ed25519_host_key +/etc/dropbear/dropbear_rsa_host_key endef define Package/dropbearconvert @@ -227,9 +228,7 @@ define Package/dropbear/install $(INSTALL_DIR) $(1)/etc/dropbear $(INSTALL_DIR) $(1)/lib/preinit $(INSTALL_DATA) ./files/dropbear.failsafe $(1)/lib/preinit/99_10_failsafe_dropbear - $(if $(CONFIG_DROPBEAR_ED25519),touch $(1)/etc/dropbear/dropbear_ed25519_host_key) - $(if $(CONFIG_DROPBEAR_ECC),touch $(1)/etc/dropbear/dropbear_ecdsa_host_key) - touch $(1)/etc/dropbear/dropbear_rsa_host_key + $(foreach f,$(filter /etc/dropbear/%,$(Package/dropbear/conffiles)),$(if $(wildcard $(TOPDIR)/files/$(f)),chmod 0600 $(TOPDIR)/files/$(f) || :; )) endef define Package/dropbearconvert/install diff --git a/package/network/services/dropbear/files/dropbear.init b/package/network/services/dropbear/files/dropbear.init index 18273e63d0..6a0fc67351 100755 --- a/package/network/services/dropbear/files/dropbear.init +++ b/package/network/services/dropbear/files/dropbear.init @@ -12,28 +12,52 @@ PIDCOUNT=0 extra_command "killclients" "Kill ${NAME} processes except servers and yourself" +# most of time real_stat() will be failing +# due to missing "stat" binary (by default) +real_stat() { env stat -L "$@" 2>/dev/null ; } +dumb_stat() { ls -Ldln "$1" | tr -s '\t ' ' ' ; } +stat_perm() { real_stat -c '%A' "$1" || dumb_stat "$1" | cut -d ' ' -f 1 ; } +stat_owner() { real_stat -c '%u' "$1" || dumb_stat "$1" | cut -d ' ' -f 3 ; } + _dropbearkey() { - /usr/bin/dropbearkey "$@" 0<&- 1>&- 2>&- + /usr/bin/dropbearkey "$@" /dev/null 2>&1 } -# $1 - host key file name -hk_verify() +# $1 - file name (host key or config) +file_verify() { [ -f "$1" ] || return 1 - [ -s "$1" ] || return 2 - _dropbearkey -y -f "$1" || return 3 + # checking file ownership + [ "$(stat_owner "$1")" = "0" ] || { + chown 0 "$1" + [ "$(stat_owner "$1")" = "0" ] || return 2 + } + # checking file permissions + [ "$(stat_perm "$1")" = "-rw-------" ] || { + chmod 0600 "$1" + [ "$(stat_perm "$1")" = "-rw-------" ] || return 3 + } + # file is host key or not? + # if $2 is empty string - file is "host key" + # if $2 is non-empty string - file is "config" + [ -z "$2" ] || return 0 + # checking file contents (finally) + [ -s "$1" ] || return 4 + _dropbearkey -y -f "$1" || return 5 return 0 } -# $1 - hk_verify() return code -hk_errmsg() +# $1 - file_verify() return code +file_errmsg() { case "$1" in 0) ;; 1) echo "file does not exist" ;; - 2) echo "file has zero length" ;; - 3) echo "file is not valid host key or not supported" ;; + 2) echo "file has wrong owner (must be owned by root)" ;; + 3) echo "file has wrong permissions (must not have group/other write bit)" ;; + 4) echo "file has zero length" ;; + 5) echo "file is not valid host key or not supported" ;; *) echo "unknown error" ;; esac } @@ -43,58 +67,83 @@ hk_errmsg() hk_config() { local x m - hk_verify "$2"; x=$? - case "$x" in - 0) procd_append_param command -r "$2" - ;; - *) m=$(hk_errmsg "$x") - logger -t "${NAME}" -p daemon.warn \ - "option '$1', value '$2': $m, skipping" - ;; - esac + file_verify "$2" ; x=$? + if [ "$x" = 0 ] ; then + procd_append_param command -r "$2" + return + fi + m=$(file_errmsg "$x") + logger -s -t "${NAME}" -p daemon.warn \ + "Option '$1', skipping '$2': $m" } # $1 - host key file name -hk_config__keyfile() -{ - hk_config 'keyfile' "$1" -} +hk_config__keyfile() { hk_config keyfile "$1" ; } + +ktype_all='ed25519 ecdsa rsa' hk_generate_as_needed() { - local kdir kgen ktype tdir kcount tfile - kdir='/etc/dropbear' + local hk_cfg_dir kgen ktype kfile hk_tmp_dir + hk_cfg_dir='/etc/dropbear' + + [ -d "${hk_cfg_dir}" ] || mkdir -p "${hk_cfg_dir}" - kgen='' - for ktype in ed25519 ecdsa rsa; do - hk_verify "${kdir}/dropbear_${ktype}_host_key" && continue + kgen= + for ktype in ${ktype_all} ; do + kfile="${hk_cfg_dir}/dropbear_${ktype}_host_key" - kgen="${kgen} ${ktype}" + if file_verify "${kfile}" ; then continue ; fi + + kgen="${kgen}${kgen:+ }${ktype}" done - [ -z "${kgen}" ] && return + # all keys are sane? + [ -n "${kgen}" ] || return 0 + + hk_tmp_dir=$(mktemp -d) + # system in bad state? + [ -n "${hk_tmp_dir}" ] || return 1 - tdir=$(mktemp -d); chmod 0700 "${tdir}" + chmod 0700 "${hk_tmp_dir}" - kcount=0 - for ktype in ${kgen}; do - tfile="${tdir}/dropbear_${ktype}_host_key" + for ktype in ${kgen} ; do + kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key" - if ! _dropbearkey -t ${ktype} -f "${tfile}"; then + if ! _dropbearkey -t ${ktype} -f "${kfile}" ; then # unsupported key type - rm -f "${tfile}" + rm -f "${kfile}" continue fi - kcount=$((kcount+1)) + chmod 0600 "${kfile}" + done + + kgen= + for ktype in ${ktype_all} ; do + kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key" + + [ -s "${kfile}" ] || continue + + kgen="${kgen}${kgen:+ }${ktype}" done - if [ ${kcount} -ne 0 ]; then - mkdir -p "${kdir}"; chmod 0700 "${kdir}"; chown root "${kdir}" - mv -f "${tdir}/"* "${kdir}/" + if [ -n "${kgen}" ] ; then + for ktype in ${kgen} ; do + kfile="${hk_tmp_dir}/dropbear_${ktype}_host_key" + [ -s "${kfile}" ] || continue + mv -f "${kfile}" "${hk_cfg_dir}/" + done fi - rm -rf "${tdir}" + rm -rf "${hk_tmp_dir}" + + # cleanup empty files + for ktype in ${ktype_all} ; do + kfile="${hk_cfg_dir}/dropbear_${ktype}_host_key" + + [ -s "${kfile}" ] || rm -f "${kfile}" + done } append_ports() @@ -207,6 +256,7 @@ boot() start_service() { hk_generate_as_needed + file_verify /etc/dropbear/authorized_keys config . /lib/functions.sh . /lib/functions/network.sh