#!/bin/bash


#Preupgrade Assistant performs system upgradability assessment
#and gathers information required for successful operating system upgrade.
#Copyright (C) 2013 Red Hat Inc.
#Petr Lautrbach <plautrba@redhat.com>
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.
. /usr/share/preupgrade/common.sh
check_applies_to "openssh-server"
#END GENERATED SECTION

back_up_config() {
    #
    # Back up the config file. In case of failure log_error as we didn't expect
    # failure could occur here.
    #
    mkdir -p $(dirname "$2")
    cp -a "$1" "$2" || {
        log_error "Cannot store the $1 file as $2."
        return 1
    }

    return 0
}

ret=$RESULT_PASS
set_result() {
    case $1 in
        $RESULT_FAIL)  ret=$1 ;;
        $RESULT_FIXED) [ $ret -ne $RESULT_FAIL ] && ret=$1 ;;
    esac
}

manual_action="no"
log_and_fail() {
    manual_action="yes"
    log_high_risk "$1"
    set_result $RESULT_FAIL
}

CLEANCONF_D="$VALUE_TMP_PREUPGRADE/cleanconf"
DIRTYCONF_D="$VALUE_TMP_PREUPGRADE/dirtyconf"

SSHD_CONFIG_FILE="/etc/ssh/sshd_config"
SSHD_CONFIG_TMP="$PWD/sshd.tmp"
CLEANCONF_SSHD="${CLEANCONF_D}${SSHD_CONFIG_FILE}"
DIRTYCONF_SSHD="${DIRTYCONF_D}${SSHD_CONFIG_FILE}"

back_up_config "$SSHD_CONFIG_FILE" "$SSHD_CONFIG_TMP" || exit_error

if grep -q "^[[:space:]]*RequiredAuthentications2" $SSHD_CONFIG_FILE; then
    msg="* RequiredAuthentications2 is replaced by AuthenticationMethods"
    msg+=" on the CentOS 7 system. For more information"
    msg+=" about AuthenticationMethods, see the SSHD_CONFIG(5) man page."
    echo -e "$msg\n" >> solution.txt

    log_info "RequiredAuthentication2 will be replaced by AuthenticationMethods."
    set_result $RESULT_FIXED

    sed -i -e 's/^\([[:space:]]*\)RequiredAuthentications2/\1AuthenticationMethods/i' $SSHD_CONFIG_TMP \
      || log_and_fail "Replacing RequiredAuthentication2 failed."
fi

if grep -q "^[[:space:]]*RequiredAuthentications1" $SSHD_CONFIG_FILE; then
    # NOTE:
    # After some inspection, the user can specify/use both on CentOS 6
    # (RequiredAuthentications[12]) in the same time. However don't know how
    # to enable SSH-1 on CentOS 7 system. It seems that best solution here is to
    # comment out completely the line with RequiredAuthentications1. We expect
    # it could be used rarely only as it is too unsafe protocol for a long
    # time.
    msg="* RequiredAuthentications1 is not supported on the CentOS Enterprise"
    msg+=" Linux 7 system, and it will be commented out automatically in the"
    msg+=" configuration file. To specify the authentication"
    msg+=" methods that have to be used, use AuthenticationMethods. For more"
    msg+=" information about AuthenticationMethods, see the SSHD_CONFIG(5)"
    msg+=" man page."
    echo -e "$msg\n" >> solution.txt

    log_slight_risk "RequiredAuthentications1 will be commented out."
    set_result $RESULT_FAIL

    sed -i -e 's/^\([[:space:]]*RequiredAuthentications1\)/# \1/i' $SSHD_CONFIG_TMP \
      || log_and_fail "RequiredAuthentications1 has not been commented out."
fi

if grep -q -i "^[[:space:]]*AuthorizedKeysCommand[[:space:]]" $SSHD_CONFIG_FILE; then
    if grep -q -i "^[[:space:]]*AuthorizedKeysCommandRunAs[[:space:]]" $SSHD_CONFIG_FILE; then
        msg="* The AuthorizedKeysCommandRunAs option is not supported in"
        msg+=" CentOS 7, and it will be replaced by"
        msg+=" AuthorizedKeysCommandUser. For more information about"
        msg+=" AuthorizedKeysCommandUser, see the SSHD_CONFIG(5) man page."
        echo -e "$msg\n" >> solution.txt

        log_info "AuthorizedKeysCommandRunAs will be replaced by AuthorizedKeysCommandUser."
        set_result $RESULT_FIXED

        sed -i -e 's/^\([[:space:]]*\)AuthorizedKeysCommandRunAs\([[:space:]]\)/\1AuthorizedKeysCommandUser\2/i' $SSHD_CONFIG_TMP \
          || log_and_fail "Replacing AuthorizedKeysCommandRunAs failed."
    else
        msg="* The AuthorizedKeysCommand option requires the AuthorizedKeysCommandUser"
        msg+=" option, which will be added automatically."
        msg+=" For more information, see the SSHD_CONFIG(5) man page."
        echo -e "$msg\n" >> solution.txt

        log_info "AuthorizedKeysCommandUser will be added into the sshd_config file."
        set_result $RESULT_FIXED
        echo 'AuthorizedKeysCommandUser %u' >> $SSHD_CONFIG_TMP \
          || log_and_fail "Adding the 'AuthorizedKeysCommandUser %u' line failed."
    fi
fi

# check whether the config file is compatible with CentOS 7 or has been fixed
# correctly. In that case, move it under cleanconf, otherwise dirtyconf and
# and warn user what to do!
if [ "$manual_action" == "no" ]; then
    if [ $ret -eq $RESULT_PASS ]; then
        back_up_config "$SSHD_CONFIG_TMP" "$CLEANCONF_SSHD" || exit_error
    elif [ $ret -eq $RESULT_FIXED ]; then
        back_up_config "$SSHD_CONFIG_TMP" "$CLEANCONF_SSHD" || exit_error
        msg="The modified $SSHD_CONFIG_FILE file has been stored as $CLEANCONF_SSHD,"
        msg+=" and it will be applied automatically on the target system."
        log_info "$msg"
    else
        back_up_config "$SSHD_CONFIG_TMP" "$DIRTYCONF_SSHD" || exit_error
    fi
else
    back_up_config "$SSHD_CONFIG_TMP" "$DIRTYCONF_SSHD" || exit_error
    msg="The $SSHD_CONFIG_FILE config file was not prepared for the in-place upgrade"
    msg+=" automatically. A partially prepared configuration file is located"
    msg+=" in the $DIRTYCONF_SSHD directory. Modify the file manually according"
    msg+=" to the information above, and move it to the $CLEANCONF_SSHD"
    msg+=" directory before upgrade."
    echo -e "\n$msg" >> solution.txt

    log_high_risk "The $SSHD_CONFIG_FILE file has to be prepared for upgrade manually."
fi

cp -a postupgrade.d/openssh.sh "$POSTUPGRADE_DIR/openssh.sh"
chmod +x "$POSTUPGRADE_DIR/openssh.sh"
exit $ret

