#!/live/bin/sh

### BEGIN INIT INFO
# Provides:          persist-password
# Required-Start:    console-setup
# Required-Stop:
# Should-Start:
# Should-Stop:
# Default-Start:      S
# Default-Stop:
# Short-Description:  persist-password
# Description:        Forces password changes for live persistence
#
### END INIT INFO

# GETTEXT_KEYWORD="gt"
# GETTEXT_KEYWORD="pfgt"

export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/live/bin

test -d /live/config/tsplash && DO_TSPLASH=true

NEW_PASSWORD_CONF=/live/config/new-passwords

main() {
    : ${CMDLINE:=$(cat /live/config/proc-cmdline)}
    for param in $CMDLINE; do
        case "$param" in
            private=*|pw=*|password=*) PASSWD_USERS=${param#*=} ; PARAM_NAME=${param%%=*} ;;
                  private|pw|password) PASSWD_USERS=root,demo   ; PARAM_NAME=${param%%=*} ;;
        esac
    done

    case "$1" in
        start) do_start ;;
         stop) exit 0   ;;
            *) echo "Usage: /etc/init.d/persist-password {start|stop}"; exit 2;;
    esac
}

should_run() {
    local users=$1
    [ "$users" = "none" ]                 && return 1
    [ -n "$users" ]                       && return 0
    [ -f /live/config/save-persist ]      && return 0

    eval $(grep ^STATIC_ROOT= /live/config/initrd.out)
    [ "$STATIC_ROOT" ]                    && return 0
    return 1
}

do_start() {
    rm -f $NEW_PASSWORD_CONF
    should_run $PASSWD_USERS || exit 0

    # . /usr/share/antiX/lib/live-init-utils.sh
    . /live/lib/live-init-utils.sh

    load_translation
    [ "$PASSWD_USERS" ] && force_passwd $PASSWD_USERS && exit 0

    validate_password root root
    validate_password demo demo
    [ "$DO_TSPLASH" ] && tsplash-on

}

#---------- Subroutines -------------------------------------------------------

force_passwd() {
    local users=$1
    local vt=$(fgconsole)
    [ "$vt" = 1 ] || { chvt 1; clear; }
    
    # empty or "all" --> root,demo
    [ -z "$users" -o "$users" = "all" ] && users="root,demo"
    for user in $(echo $users | sed 's/,/ /g'); do
        forced_banner "$user"
        change_password "$user"
    done
    [ "$vt" = 1 ] || [ "$DO_TSPLASH" ] && chvt 10

    return 0
}

#-----------------------------------------------------------------------------
# function: guess_password user guess1 [guess2 ...]
# Returns true if one of the guesses matches the password for user.
# $GUESSED contains the guessed password.
#-----------------------------------------------------------------------------
guess_password() {
    local  user=$1
    shift;
    unset GUESSED
    local entry=$( grep ^$user: /etc/shadow | cut -d: -f2 )

    [ "$entry" ] || return 2

    while [ $# -gt 0 ] ; do
        local guess=$1
        shift;

        local type=$( echo "$entry" | cut -d$ -f2 )
        local salt=$( echo "$entry" | cut -d$ -f3 )
        local orig=$( echo "$entry" | cut -d$ -f4 )
        local method

        case $type in
            1) method="md5";;
            5) method="sha-256";;
            6) method="sha-512";;
           *) return 3;;
        esac

        local new=$(mkpasswd -m $method -S "$salt" "$guess" )
        if [ "$entry" = "$new" ]; then
            GUESSED="$guess"
            return 0
        fi
    done

    return 1
}

do_banner() {
    cat <<End_Banner
$CYAN*******************************************************************
                  ${RED}$(pf "$_DANGER_X_INSECURE_PASSWORD_Y_" $WHITE $CYAN)
$CYAN*******************************************************************
$NO_COLOR
End_Banner
}

do_splash() {
    user="$1"
    [ "$DID_BANNER" ] || do_banner
    DID_BANNER="true"

    local a="$(pf "$_It_appears_that_root_persistence_was_recently_enabled_")"
    local b="$(pf "$_The_default_password_for_the_X_account_is_not_secure_" "$CYAN$user$NO_COLOR")"
    local c="$(pf "$_It_was_convenient_for_a_LiveCD_but_is_not_sufficient_to_protect_a_system_with_persistence_")"
    local d="$(pf "$_Please_provide_a_more_secure_password_")"
    local e="$(pf "$_One_type_of_good_password_has_8_or_more_characters_and_contains_a_mixture_of_letters_numbers_and_punctuation_")"
    local f="$(pf "$_Sorry_for_the_slight_inconvenience_this_causes_")"

    echo "$a  $b  $c $d  $e  $f" | fold -s
}

change_password() {
    user=$1
    echo
    pf "$_username_X_" "$CYAN$user$NO_COLOR"
    echo
    passwd $user
}

#-----------------------------------------------------------------------------
# function: validate_password user guess1 [guess2 ...]
# If we guess the password for <user> then we force the user to change that
# password.  We don't quit until it's changed.
#-----------------------------------------------------------------------------
validate_password(){
    local user=$1
    guess_password "$@" || return

    touch $NEW_PASSWORD_CONF

    [ "$DO_TSPLASH" ] && tsplash_clear

    do_splash "$user" $GUESSED
    change_password "$user"
    while guess_password "$@"; do
        echo "$YELLOW----------------------------------------------------$NO_COLOR"
        pf "$_The_X_password_hasnt_changed_Please_try_again_"  "$CYAN$user$NO_COLOR"
        echo
        echo "$YELLOW----------------------------------------------------$NO_COLOR"
        change_password "$user"

        #count=$(( $count + 1 ))
        #[ "$count" -gt 1 ] && return
    done
}

forced_banner() {
    local user=$1
    cat <<End_FBanner
$CYAN-------------------------------------------------------------------$NO_COLOR
        $(pf "$_Changing_password_for_account_X_as_requested_"  "$CYAN$user$NO_COLOR")
        $(pf "$_by_use_of_the_X_boot_parameter_" "$GREEN$PARAM_NAME$NO_COLOR")
$CYAN-------------------------------------------------------------------$NO_COLOR
End_FBanner
}

#------------------------------------------------------------------------------
#
#------------------------------------------------------------------------------
tsplash_clear() {
    [ "$DO_TSPLASH" ] || return

    if [ -z "$TSPLASH_CLEARED" ]; then
        clear
        sleep .2
        TSPLASH_CLEARED=true
    fi
    chvt 1
}

#------------------------------------------------------------------------------
#---------- Main Code Starts Here ---------------------------------------------
#------------------------------------------------------------------------------


main "$@"

exit 0


