#!/bin/bash

PREREQ="system-layer"

prereqs()
{
    echo "$PREREQ"
}

case $1 in
    prereqs)
        prereqs
        exit 0
        ;;
esac

. /scripts/functions
. /scripts/security-functions

securityfs_mnt=/sys/kernel/security
ksaf_status_path="$securityfs_mnt/ksaf/status"

securityfs_is_mounted()
{
	mount -t securityfs | awk '{print $3}' | while read mntdir
	do
	    if [ "$mntdir" = "$securityfs_mnt" ]; then
			echo "yes"
			return
		fi
	done

	echo "no"
}

if [ "yes" != `securityfs_is_mounted` ]; then
	mount -t securityfs none "$securityfs_mnt"
	if [ $? -ne 0 ]; then
		panic "Failed to mount securityfs"
		exit 0
	fi
fi

ksaf_status=0

set_ksaf_status()
{
	echo $1 > $ksaf_status_path
}

if ! grep -q " ${rootmnt} .*rw" /proc/mounts; then
	mount -o remount,rw ${ROOT} ${rootmnt}
fi

machine=`uname -m`

ksaf_tmp=${rootmnt}/etc/ksaf/tmp
ksaf_conf_file=${rootmnt}/etc/ksaf/mod_conf/ksaf_main.conf
ostree_snap_file=${rootmnt}/etc/ostree/security/snap-status

if [ -e "$ksaf_conf_file" ]; then
	ksaf_status=$(cat "$ksaf_conf_file")
fi

relabel_flag=1
kyexectl_flag=0
relabel_file=$ksaf_tmp/.status

get_relabel_flag()
{
	if [ -f "$relabel_file" ]; then
		status=$(cat "$relabel_file")
		if [ "x$status" = "x0" ]; then
			relabel_flag=0
		elif [ "x$status" = "x6" ]; then
			relabel_flag=6
		elif [ "x$status" = "x8" ]; then
			relabel_flag=8
		elif [ "x$status" = "x10" ]; then
			relabel_flag=10
		fi
	fi
	if [ -f "$ostree_snap_file" ]; then
		if cat "$ostree_snap_file" | grep -q "restore"; then
			kyexectl_flag=1
		fi
	fi
}

ksaf_label_manager=/usr/sbin/ksaf-label-manager
kyexectl_tool=/usr/sbin/kyexectl
. ${rootmnt}/etc/default/locale

# 根据安装系统选择的语言设置，选择要显示的语言
# $1 为中文
# $2 为繁体
# $3 为英文
# $4 为藏文
# 非以上四种语言环境默认显示英文
translate_message()
{
	case "$LANG" in
		zh_CN.*)
			echo "$1"
		;;
		zh_HK.*)
			echo "$2"
		;;
		en_US.*)
			echo "$3"
		;;
		bo_CN.*)
			echo "$4"
		;;
		mn_MN.*)
			echo "$5"
		;;
		kk_KZ.*)
			echo "$6"
		;;
		ug_CN.*)
			echo "$7"
		;;
		ky_KG.*)
			echo "$8"
		;;
		vi_VN.*)
			echo "$9"
		;;
		ms_MY.*)
			echo "${10}"
		;;
		th_TH.*)
			echo "${11}"
		;;
		*)
			echo "$3"
		;;
	esac
}

#系统overlay配置文件路径
OVERLAY_CONF="/root/sysroot/ostree/pkgs/system-ovl.conf"

# 表示当前系统所处的模式：
#   - maintain[M]：运维模式
#   - normal[N]：用户模式
overlay_mod_conf=N

path_pre=
stage_initrd=
deploy=

#usr的overlay各路径
Usr_LowerDir=
Usr_UpperDir=
Usr_WorkDir=
Usr_MergeDir=

get_mode_conf()
{
    mode=$(grep '^Mode=' "$OVERLAY_CONF" | awk -F'=' '{print $2}')
    if [ "$mode" = "maintain" ];then
        overlay_mod_conf=M
    fi
}

# 函数：替换占位符
replace_placeholders()
{
    local input="$1"
    input="${input//<PathPre>/$path_pre}"
    input="${input//<stage>/$stage_initrd}"
    input="${input//<Deploy>/$deploy}"
    echo "$input"
}

get_preparation_value()
{
	# 提取StageInitrd的值
    stage_initrd=$(awk -F'=' '/^StageInitrd=/ {print $2}' "$OVERLAY_CONF")

    # 提取Deploy的值
    deploy=$(awk -F'=' '/^Deploy=/ {print $2}' "$OVERLAY_CONF")

    # 提取PathPre的值
    path_pre=$(awk -F'=' '/^PathPre=/ {print $2}' "$OVERLAY_CONF")
    path_pre=$(replace_placeholders "$path_pre")
}

get_usr_dir()
{
	get_preparation_value

    in_usr=false
    while IFS= read -r line; do
        if [ "$line" = "[usr-$overlay_mod_conf]" ]; then
            in_usr=true
        elif [ "${line:0:1}" = "[" ] && [ $in_usr ]; then
            in_usr=false
        fi

        if $in_usr; then
            case "$line" in
                *LowerDir=*)
                    Usr_LowerDir=$(replace_placeholders "${line#*LowerDir=}")
                    ;;
                *UpperDir=*)
                    Usr_UpperDir=$(replace_placeholders "${line#*UpperDir=}")
                    ;;
                *WorkDir=*)
                    Usr_WorkDir=$(replace_placeholders "${line#*WorkDir=}")
                    ;;
                *MergeDir=*)
                    Usr_MergeDir=$(replace_placeholders "${line#*MergeDir=}")
                    ;;
                *)
                    ;;
            esac
        fi
    done < "$OVERLAY_CONF"
}

do_remount()
{
	mount -t proc -o nodev,noexec,nosuid proc "$rootmnt/proc"
	mount -t sysfs -o nodev,noexec,nosuid sys "$rootmnt/sys"
	mount -t devtmpfs udev "$rootmnt/dev"

	#把/usr的overlay叠加去掉
	umount "$rootmnt/usr"
	#挂载/usr目录可读写
	mount -o remount,rw "$rootmnt/usr"
	mount -o remount,rw "$rootmnt/sysroot"

	DATA_DEVICE=$(awk -F'[[:space:]]+' '$1 ~ /^UUID=/ && $2 == "/data" {print $1}' "$rootmnt/etc/fstab")
	chroot "${rootmnt}" /bin/bash -c "mount $DATA_DEVICE /data"
	mount --bind $rootmnt/data/home $rootmnt/home

	zh_CN_msg="正在初始化系统配置，请稍候......"
	zh_HK_msg="正在初始化系統配置，請稍候......"
	en_CN_msg="Initializing system configuration, please wait ..."
	bo_CN_msg="འགོ་སྒྲག་མ་ལག་ཡིག་སྒྲོམ་སྒྲིག་འཛུགས། ཏོག་ཙམ་སྒུག་རོགས་།"
	mn_MN_msg="ᠣᠳᠣ ᠶᠠᠭ ᠰᠢᠰᠲ᠋ᠧᠮ ᠦᠨ ᠲᠣᠭᠠᠯᠭᠠ ᠯ ᠡᠬᠢᠵᠢᠬᠦᠯᠵᠦ ᠪᠠᠢ᠌ᠨᠠ ᠂ ᠲᠦᠷ ᠬᠦᠯᠢᠶᠡᠵᠦ ᠪᠠᠢ᠌ᠭᠠᠷᠠᠢ ......"
	kk_KZ_msg="ﺝۇﻱە ﺳﺍﭘﺗﺍﺭﺍۋﯞﻯﺍﺴﺗﯩﻧ ﺑﺎﺴﺗﺍۋﻯﭘ ﻭﺗﻯﺭ، ﻙۇﺗﻯڭﻻﺭ......"
	ug_CN_msg="ﺱﻰﺴﺗېﻡﺍ ﺳﯧﺯﻟﯩﻣﯩﺳﻰﻧﻯ ﺩەﺲﻟەﭗﻛﻰ ﻕەﺩەﻡﺩە ﺏﺎﺷﻻۋﺎﺗﻯﺩۇ، ﺱﺎﻗﻼﭘ ﺕۇﺭۇڭ......"
	ky_KG_msg="ﺱﻰﺴﺗېﻡﺍ ﺳﯧﺯﻟﯩﻣﯩﺳﻰﻥ ﺩەﺲﻟەﭗﻛﻯ ﺏﺎﺷﺗﺎﭖ ﺝﺎﺗﺎﺕ، ﺱﺎﻗﺘﺎﭖ ﺕۇﺭۇڭۇﺯ......"
	vi_VN_msg="Đang khởi tạo cấu hình hệ thống, vui lòng đợi......"
	ms_MY_msg="Sedang memulakan konfigurasi sistem, sila tunggu......"
	th_TH_msg="กำลังเตรียมการกำหนดค่าระบบ โปรดรอสักครู่......"
	msg="$(translate_message "$zh_CN_msg" "$zh_HK_msg" "$en_CN_msg" "$bo_CN_msg" "$mn_MN_msg" "$kk_KZ_msg" "$ug_CN_msg" "$ky_KG_msg" "$vi_VN_msg" "$ms_MY_msg" "$th_TH_msg")"
	show_message "$msg"

	echo "relabel_flag : $relabel_flag" > /tmp/ksaf-init.log
	if [ -e "$ksaf_tmp/ostree-factory-restore" ] || [ "x$relabel_flag" = "x0" ]; then
		chroot "${rootmnt}" /bin/bash -c "/bin/mount -a; ${ksaf_label_manager} -d /"
	elif [ "x$status" = "x6" ]; then
		chroot "${rootmnt}" /bin/bash -c "/bin/mount -a; ${ksaf_label_manager} -s"
	elif [ "x$relabel_flag" = "x8" ]; then
		chroot "${rootmnt}" /bin/bash -c "/bin/mount -a; ${ksaf_label_manager} -d / -r"
	elif [ "x$relabel_flag" = "x10" ]; then
		if [ -f /tmproot/ostree/pkgs/ovl-${deploy_csum_serial}/usr-ovl/usr-tmpupper/sbin/ksaf-label-manager ]; then
			chroot "${rootmnt}" /bin/bash -c "/bin/mount -a; /ostree/pkgs/ovl-${deploy_csum_serial}/usr-ovl/usr-tmpupper/sbin/ksaf-label-manager -i /"
		elif [ -f /tmproot/ostree/pkgs/ovl-${deploy_csum_serial}/usr-ovl/usr-lower/sbin/ksaf-label-manager ]; then
			chroot "${rootmnt}" /bin/bash -c "/bin/mount -a; /ostree/pkgs/ovl-${deploy_csum_serial}/usr-ovl/usr-lower/sbin/ksaf-label-manager -i /"
		else
			chroot "${rootmnt}" /bin/bash -c "/bin/mount -a; ${ksaf_label_manager} -i /"
		fi
	fi

	if [ -e "$ksaf_tmp/ostree-factory-restore" ]; then
		rm $ksaf_tmp/ostree-factory-restore
	fi

	if [ -e "$ksaf_tmp/.status_updateos" ]; then
		touch /tmp/.status_updateos
	fi

	if [ -e "$ksaf_tmp/.status_update" ]; then
		touch /tmp/.status_update
	fi
	

	#挂载/usr目录只读
	mount -o ro,bind,remount "$rootmnt/usr" "$rootmnt/usr"
	mount -o rw,bind,remount "/tmproot" "$rootmnt/sysroot"

	if [ "x$machine" != "xsw_64" ]; then
		#加载/usr的overlay叠加
		if [ "${overlay_mod_conf}" = "N" ]; then
			mount -t overlay overlay -o lowerdir=${Usr_LowerDir},workdir=${Usr_WorkDir} ${Usr_MergeDir}
		else
			mount -t overlay overlay -o lowerdir=${Usr_LowerDir},upperdir=${Usr_UpperDir},workdir=${Usr_WorkDir} ${Usr_MergeDir}
		fi
	else
		#加载/usr的overlay叠加
		if [ "${overlay_mod_conf}" = "N" ]; then
			mount -t overlay overlay -o lowerdir=${Usr_LowerDir},workdir=${Usr_WorkDir},index=off ${Usr_MergeDir}
		else
			mount -t overlay overlay -o lowerdir=${Usr_LowerDir},upperdir=${Usr_UpperDir},workdir=${Usr_WorkDir},index=off ${Usr_MergeDir}
		fi
	fi

	umount "$rootmnt/dev"
	umount "$rootmnt/sys"
	umount "$rootmnt/proc"
}

do_relabel()
{
	local level=`cat /proc/sys/kernel/printk | awk '{print $1}'`

	echo 1 > /proc/sys/kernel/printk

	get_mode_conf

	get_usr_dir

	do_remount
	# enable kernel messages
	echo "$level" > /proc/sys/kernel/printk
	clear_message
}

cmdline=$(cat /proc/cmdline)

if echo "$cmdline" | grep -qE 'lsm=([^,]+,)*[^,]*ksaf([^,]*|$)'; then
	#获取ksaf_status，如果ksaf关闭，则记录status并退出脚本
	#如果ksaf使能，判断是否需要relabel，并记录status
	if [ "$ksaf_status" -eq 0 ]; then
		echo "$ksaf_status" > $relabel_file
		set_ksaf_status $ksaf_status
	else
		get_relabel_flag
		if [ -e "$ksaf_tmp/ostree-factory-restore" ] || [ "x$relabel_flag" = "x0" ] || [ "x$relabel_flag" = "x6" ] || [ "x$relabel_flag" = "x8" ] || [ "x$relabel_flag" = "x10" ]; then
			do_relabel
		fi
		if [ "$kyexectl_flag" = "1" ]; then
			chroot "${rootmnt}" /bin/bash -c  "/bin/mount -a; ${kyexectl_tool} -a"
		fi

		case "$ksaf_status" in
			2|4)
				chroot "${rootmnt}" /bin/bash -c  "/bin/mount -a; ${kyexectl_tool} -s -o /opt/certaide.kylin/files/driver/*"
				set_ksaf_status $ksaf_status
				;;
		esac
		echo "$ksaf_status" > $relabel_file
	fi

	if echo "$cmdline" | grep -q "ostree-factory-restore";	 then
		touch $ksaf_tmp/ostree-factory-restore
	fi
else
	echo 0 > $relabel_file
fi


