#!/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
    # 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

    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!%s INSECURE PASSWORD!%s" $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 %s 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: %s" "$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 %s password hasn't 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 %s as requested"  "$CYAN$user$NO_COLOR")
        $(pf "by use of the %s 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


