#!/bin/bash

#
# Copyright (c) Citrix Systems 2018. All rights reserved.
#

# This script performs some of the steps needed to put a freshly installed
# XenServer into the evaluated configuration for Common Criteria security
# certification.

set -e

. ${XENSOURCE_INVENTORY}

config_xapi_client() {
    # Turn on SSL certificate verification.
    touch /var/xapi/verify_certificates
    echo "Created /var/xapi/verify_certificates"
}

config_firewall() {
    # Make sure the firewall is turned on
    systemctl start iptables.service
    
    # Load default rules
    iptables-restore < ${FIRSTBOOT_DATA_DIR}/common_criteria_firewall_rules

    # Insert sshd rule
    # Here accept sshd port traffic if host-installer already enabled sshd service,
    # which happens only in automation installation through answer file. After the
    # port enabling, automation test is able to make further configuraton for XS
    # through ssh, that's the reason to add the rule.
    systemctl is-enabled --quiet sshd.service && \
        iptables -I INPUT 4 -i xenbr0 -p tcp --dport 22 -m state --state NEW -j ACCEPT

    # Save the new firewall configuration and ensure it is turned on after reboot.
    service iptables save
    systemctl enable iptables.service
    
    echo "Enabled firewall"
}

rename_network_label() {
    # In common criteria certification deployment, user must ensure:
    # - The 1st NIC (eth0) is for Management Network
    # - The 2nd NIC (eth1) is for Storage Network
    # - others (ethX, X>=2) is for Guest Network
    # This function is to rename these network labels to appropriate.
    for device in $(ls /sys/class/net | grep -E '^eth[0-9]+$')
    do
        device_id=$(echo ${device} | sed 's/^eth//')
        if [ ${device_id} -eq 0 ]; then
            name_label="Management Network"
        elif [ ${device_id} -eq 1 ]; then
            name_label="Storage Network"
        elif [ ${device_id} -ge 2 ]; then
            name_label="Guest Network $((${device_id} - 2))"
            pif_uuid=$(${XE} pif-list device=${device} params=uuid --minimal)
            ${XE} pif-reconfigure-ip uuid="${pif_uuid}" mode=none
        else
            echo "Warning: found unsupported device ${device}"
            continue
        fi
        
        network_uuid=$(${XE} pif-list device=${device} params=network-uuid --minimal)
        ${XE} network-param-set uuid=${network_uuid} name-label="${name_label}"
        echo "Renamed network label of ${network_uuid} to ${name_label}, device: ${device}"
    done
}

config_pool_secret() {
    # Get libcrypto.so full path from CCM
    ccm="citrix-crypto-module"
    libcrypto=$(rpm -ql ${ccm} | grep "/libcrypto.so" | head -n 1)
    if [ "${libcrypto}" == "" ]; then
        echo "Error: could not find ${ccm}"
        exit 1
    fi
    
    # Generate pool secret
    echo -n $"Creating pool secret using ${libcrypto} (this may take some seconds)"
    pool_secret=$(/bin/pool_secret ${libcrypto})
    if [ $? -ne 0 ]; then
        echo "Error: failed to generate pool secret"
        exit 1
    fi
    
    # Write pool secret to file
    token_path="/etc/xensource/ptoken"
    touch ${token_path} && chmod 640 ${token_path} && echo -n ${pool_secret} > ${token_path}
    echo ' ...done.'
    
    # Restart xapi to make it read the new ptoken we have just created.
    systemctl restart xapi.service
    # and wait for it to be fully started
    xapi_startup_cookie="/var/run/xapi_startup.cookie"
    xapi_init_complete_cookie="/var/run/xapi_init_complete.cookie"
    until [ -e ${xapi_startup_cookie} -a -e ${xapi_init_complete_cookie} ]; do
        sleep 1
    done
    
    echo "Configured pool secret"
}

start() {
    if [ "${CC_PREPARATIONS}" != "true" ]; then
        echo "Skipped common criteria settings"
        return
    fi
    
    config_xapi_client
    config_firewall
    rename_network_label
    config_pool_secret
}

case $1 in
    start) start;;
    *) exit
esac
