diff --git a/sshmngr/files/common/etc/init.d/sshmngr b/sshmngr/files/common/etc/init.d/sshmngr index eb0f4937f..499a9c382 100755 --- a/sshmngr/files/common/etc/init.d/sshmngr +++ b/sshmngr/files/common/etc/init.d/sshmngr @@ -5,7 +5,10 @@ USE_PROCD=1 . /lib/sshmngr/sshmngr.sh -service_triggers() { +start_service() { configure_ssh - procd_add_reload_trigger sshmngr +} + +service_triggers() { + procd_add_reload_trigger "sshmngr" } diff --git a/sshmngr/files/common/lib/sshmngr/sshmngr.sh b/sshmngr/files/common/lib/sshmngr/sshmngr.sh index 79babb07c..7fea365b4 100755 --- a/sshmngr/files/common/lib/sshmngr/sshmngr.sh +++ b/sshmngr/files/common/lib/sshmngr/sshmngr.sh @@ -2,12 +2,13 @@ . /lib/sshmngr/backend.sh -TEMP_UCI_PATH="/tmp/sshmngr" +SSHMNGR_SECTIONS="" handle_server_section() { local cfg="$1" - local enable + local TargetSectionType="$2" + local TargetUci="$3" local PasswordAuth="" local Port="" local RootPasswordAuth="" @@ -17,11 +18,10 @@ handle_server_section() local IdleTimeout="" local MaxAuthTries="" local ServerName="${cfg}" + local enable config_get_bool enable $cfg enable 0 - [ $enable -eq 0 ] && return - config_get PasswordAuth $cfg PasswordAuth config_get Port $cfg Port config_get RootPasswordAuth $cfg RootPasswordAuth @@ -31,34 +31,97 @@ handle_server_section() config_get IdleTimeout $cfg IdleTimeout config_get MaxAuthTries $cfg MaxAuthTries - # add section - uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName=$CONFIG + # if someone does not want sshmngr to over-write/delete a section + # they can set option BbfSection to 0 in the BACKEND UCI + local BbfSection="$(uci -q get $TargetUci.$ServerName.BbfSection)" + + # if section exists and its BbfSection flag is not 1 or true, then it means it was added by user + # so we don't modify it and return + if uci -q get $TargetUci.$ServerName >/dev/null 2>&1; then + if [ -z "$BbfSection" ] || [ "$BbfSection" == "0" ] || [ "$BbfSection" == "false" ]; then + return + fi + fi + + # adding a section using uci set instead of uci add + # because if a section is not present then we want to add it + # if it is present then silently move on + uci -q set $TargetUci.$ServerName=$TargetSectionType + + # set BbfSection to 1 so that in future we will know that this + # section was added by us + uci -q set $TargetUci.$ServerName.BbfSection=1 # set options - [ -n "$PasswordAuth" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.PasswordAuth=$PasswordAuth - [ -n "$Port" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.Port=$Port - [ -n "$RootPasswordAuth" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.RootPasswordAuth=$RootPasswordAuth - [ -n "$RootLogin" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.RootLogin=$RootLogin - [ -n "$Interface" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.Interface=$Interface - [ -n "$SSHKeepAlive" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.SSHKeepAlive=$SSHKeepAlive - [ -n "$IdleTimeout" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.IdleTimeout=$IdleTimeout - [ -n "$MaxAuthTries" ] && uci -c "$TEMP_UCI_PATH" set $CONFIG.$ServerName.MaxAuthTries=$MaxAuthTries + [ -n "$PasswordAuth" ] && uci -q set $TargetUci.$ServerName.PasswordAuth=$PasswordAuth + [ -n "$Port" ] && uci -q set $TargetUci.$ServerName.Port=$Port + [ -n "$RootPasswordAuth" ] && uci -q set $TargetUci.$ServerName.RootPasswordAuth=$RootPasswordAuth + [ -n "$RootLogin" ] && uci -q set $TargetUci.$ServerName.RootLogin=$RootLogin + [ -n "$Interface" ] && uci -q set $TargetUci.$ServerName.Interface=$Interface + [ -n "$SSHKeepAlive" ] && uci -q set $TargetUci.$ServerName.SSHKeepAlive=$SSHKeepAlive + [ -n "$IdleTimeout" ] && uci -q set $TargetUci.$ServerName.IdleTimeout=$IdleTimeout + [ -n "$MaxAuthTries" ] && uci -q set $TargetUci.$ServerName.MaxAuthTries=$MaxAuthTries + [ -n "$enable" ] && uci -q set $TargetUci.$ServerName.enable=$enable + + # keep a list of sshmngr sections + # this will be compared with backend sections later + # so that extra sections can be deleted + SSHMNGR_SECTIONS="${SSHMNGR_SECTIONS} $ServerName" +} + +# if a section has been deleted from sshmngr UCI +# then we cannot detect which section has been deleted by looping on sshmngr UCI +# so loop on backend UCI and delete sections that are not present in sshmngr UCI +remove_extra_sections() +{ + local TargetUci="$1" + local TargetSectionType="$2" + local BbfSection="" + local TargetSection="" + + # get a list of sections present in backend uci + TargetSections="$(uci -qX show $TargetUci | awk -F. '{print $2}' | sort -u | grep -vF "=${TargetSectionType}")" + + for TargetSection in $TargetSections; do + # if someone does not want sshmngr to over-write a section + # they can set option BbfSection to 0 in the BACKEND UCI + BbfSection="$(uci -q get $TargetUci.$TargetSection.BbfSection)" + + if [ "$BbfSection" == "1" ] || [ "$BbfSection" == "true" ]; then + if ! echo "$SSHMNGR_SECTIONS" | grep -q $TargetSection; then + uci -q delete $TargetUci.$TargetSection + fi + fi + done } configure_ssh() { - # remove temp UCI - rm -rf "$TEMP_UCI_PATH"/$CONFIG 2>/dev/null - mkdir -p "$TEMP_UCI_PATH" - touch "$TEMP_UCI_PATH"/$CONFIG + local TargetUci="$CONFIG" + local CurrentUci="sshmngr" + local TargetSectionType="$CONFIG" + local CurrentSectionType="server" - # read all sshmngr server sections and then apply them to $CONFIG UCI - config_load sshmngr - config_foreach handle_server_section server + # if this is the first time sshmngr is running + if [ ! -f /etc/sshmngr/first_run_flag ]; then + # create first_run_flag + mkdir -p /etc/sshmngr/ + echo "0" > /etc/sshmngr/first_run_flag + # when sshmngr runs for the first time + # it enforces its own UCI on the backend + # so, remove TargetUci + rm /etc/config/$TargetUci + fi - uci -c "$TEMP_UCI_PATH" commit $CONFIG + # if TargetUci is not present then create it + [ -f /etc/config/$TargetUci ] || touch /etc/config/$TargetUci - cp "$TEMP_UCI_PATH"/$CONFIG /etc/config/$CONFIG + # read all current sections and then apply them to target + config_load "$CurrentUci" + config_foreach handle_server_section "$CurrentSectionType" "$TargetSectionType" "$TargetUci" - /etc/init.d/$CONFIG reload + remove_extra_sections "$TargetUci" "$TargetSectionType" + + # do not use single quotes, that gives error + ubus call uci commit "{\"config\":\"$TargetUci\"}" }