#!/bin/bash
# Atomic Secured Linux
# Name: asl
# Copyright Atomicorp 2018
# Summary:  Atomic Secured Linux installer
# License: Commercial. Unauthorized redistribution prohibited.


INSTALLER_VER=6.1.9
export LANG=C

SERVER=www.atomicorp.com
ARCH=`uname -i`
GET=/usr/bin/wget
SOURCEINSTALL=0
ALT_REPO_DISABLED=0
ROOT_UID="0"
LOG=/root/tortix-install.log
DATE=$(date +%Y%m%d-%H:%M)
BETA=0

function app_exit {
	EXIT_CODE=$1
	echo

	# re-enable disabled repos
	if [ $ALT_REPO_DISABLED -ge 1 ]; then
		for reponame in $ALT_REPO; do
			/usr/bin/yum-config-manager --enable $reponame > /dev/null
		done
	fi

	# remove lock file
	rm -f /asl-installer.lock

	# exit
	exit $EXIT_CODE
}

# make sure no instance of the installer is running
if [ -f /asl-installer.lock ]; then
	echo "Another installer is already running."
	app_exit 1
else
	touch /asl-installer.lock
fi

#Check if run as root
# For environments that do not use bash.
if [ ! "$UID" ]; then
        UID=`id -u`
fi

if [ "$UID" -ne "$ROOT_UID" ] ; then
        echo "ERROR: You must be root to run this program."
        rm -f /asl-installer.lock
        exit 1
fi

#if [ $0 != "sh" ]; then
#	echo "ERROR: This program cannot be run locally. Please try again with:"
#	echo "	wget -q -O - http://updates/installers/asl |sh"
#	exit 1
#fi

if [ -f asl.cfg ]; then
	AUTO=1
	source ./asl.cfg
fi

# Logging
echo "Tortix install begin: $DATE" >> $LOG

if [ ! $SSH_TTY  ]; then
	INSTALL_TTY="/dev/$(ps -p$$ --no-heading | awk '{print $2}')"
else
	INSTALL_TTY=$SSH_TTY
fi
echo "Environment" >> $LOG
env >>$LOG

rawurlencode() {
  local string="${1}"
  local strlen=${#string}
  local encoded=""

  for (( pos=0 ; pos<strlen ; pos++ )); do
     c=${string:$pos:1}
     case "$c" in
        [-_.~a-zA-Z0-9] ) o="${c}" ;;
        * )               printf -v o '%%%02x' "'$c"
     esac
     encoded+="${o}"
  done
  echo "${encoded}"
  REPLY="${encoded}"
}


function cpanel_litespeed_install {
	echo
	echo "Litespeed installation detected." | tee -a $LOG
	echo "  UNSUPPORTED: Litespeed is not supported." | tee -a $LOG
	echo

	check_input "  This environment is UNSUPPORTED. Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

	if [ "$INPUTTEXT" == "no" ]; then
		echo "  Exiting...." | tee -a $LOG
		echo
		exit
	fi
        echo "WARNING: User accepted unsupported litespeed risk." >> $LOG


}

function cpanel_ea3_install {

	# Module check
	echo -n "Verifying mod_unique_id: " |tee -a $LOG
	$HTTPD -l |grep -q unique >> $LOG
	RETVAL=$?
	if [ ! "$RETVAL" = 0 ]; then
		echo "Not found."
		if [ $CPANEL ]; then
			echo
			echo "  ASL will attempt to rebuild apache with uniqueid support later " |tee -a $LOG
			echo "  in the installation" |tee -a $LOG
			echo
			BUILD_UNIQUEID=1
		else
			echo "  mod_unique_id support in apache is required. You will need to" |tee -a $LOG
			echo "  rebuild apache with support to continue installing ASL." |tee -a $LOG
			echo
			app_exit 1
		fi
		echo
		echo
	else
		echo "passed." |tee -a $LOG
		echo
	fi

	# Install libcurl-devel
	if [ "$DIST" == "el6" ]; then
		yum -y --disableexcludes=all --skip-broken  install libcurl-devel  | tee -a $LOG
		if [ ${PIPESTATUS[0]} -ge 1 ]; then
			echo "Yum libcurl-devel install failed." | tee -a $LOG
			app_exit 1
		fi
	fi


	# COMMON STUFF
	# Clear work directory
        if [ -d /root/atomic ]; then
          rm -rf /root/atomic
        fi

        mkdir /root/atomic

        cd /root/atomic/

        # Prep yum
        yum clean all >> $LOG

	# secondary error checking
	if [ ! -f /usr/bin/rpmbuild ]; then
		yum -y --disableexcludes=all --skip-broken install rpm-build  |tee -a $LOG
		if [ ${PIPESTATUS[0]} -ge 1 ]; then

			echo "	ERROR: rpmbuild could not be installed. Contact your OS vendor for further assistance." | tee -a $LOG
			app_exit 1
		fi
	fi

        # WAF build Start
	# Test X: install pcre & pcre-devel
	rpm --quiet -q pcre || yum --disableexcludes=all -y install pcre | tee -a $LOG
	rpm --quiet -q pcre-devel || yum --disableexcludes=all -y install pcre-devel | tee -a $LOG


	# Fix X: Reduce spurious header files that cause conflicts
	if [ -f /usr/local/apache/include/pcre.h ]; then
		echo "/usr/local/apache/include/pcre.h detected.... removing deprecated file" | tee -a $LOG
		rm -f /usr/local/apache/include/pcre.h
	fi

}

function cpanel_ea3_install_post {
		if [ -f /scripts/preeasyapache ]; then
			if ! egrep "template-cpanel-preeasyapache-hook.*ASL_HOOK" /scripts/preeasyapache ; then
				echo "/var/asl/data/templates/template-cpanel-preeasyapache-hook #ASL_HOOK" >> /scripts/preeasyapache

			fi
		else
			install -m0755 /var/asl/data/templates/template-cpanel-preeasyapache /scripts/preeasyapache
		fi

		if [ -f /scripts/posteasyapache ]; then
			if ! egrep "template-cpanel-apache-hook.*ASL_HOOK" /scripts/posteasyapache ; then
				echo "/var/asl/data/templates/template-cpanel-apache-hook #ASL_HOOK" >> /scripts/posteasyapache
			fi
		else
			install -m0755 /var/asl/data/templates/template-cpanel-posteasyapache /scripts/posteasyapache
		fi

		# Install modules
		if [ -f /scripts/easyapache ]; then
			/scripts/easyapache --build | tee -a $LOG
		fi
}


function cpanel_ea4_install {
	yum -y install ea-apache24-mod_security2 ea-apache24-mod_sed| tee -a $LOG
	if [ ${PIPESTATUS[0]} -ge 1 ]; then
		echo
		echo "Error: Could not install ea-apache24-modsecurity2" |tee -a $LOG
		app_exit 1
	fi

}

function cpanel_common_install {

  	# Rule storage directory location & default config
  	if [ ! -d /etc/httpd/modsecurity.d ]; then
    		mkdir -p /etc/httpd/modsecurity.d
  	fi

  	if [ ! -d /etc/httpd/conf.d ]; then
    		mkdir -p  /etc/httpd/conf.d
  	fi

	if ! rpm --quiet -q asl-stream-client; then
		yum --disableexcludes=all -y install asl-stream-client clamd paxtest| tee -a $LOG
		if [ ${PIPESTATUS[0]} -ge 1 ]; then
			echo
			echo "Error: Could not install  asl-stream-client clamd paxtest" |tee -a $LOG
			app_exit 1
		fi

	fi

	if ! rpm --quiet -q psmon; then

		if [ -h /usr/bin/perl ]; then
			echo "ERROR: damaged /usr/bin/perl detected. " | tee -a $LOG
			echo "  Cpanel has broken perl on your system, contact cpanel for support.  " | tee -a $LOG
			echo "  PSMON cannot be installed... " | tee -a $LOG
			echo "  logging data, please stand by" | tee -a $LOG
			sleep 10
			else
			yum --disableexcludes=all -y install psmon | tee -a $LOG
			if [ ${PIPESTATUS[0]} -ge 1 ]; then
				echo
				echo "Error: Could not install psmon" |tee -a $LOG
				echo "  PSMON is not supported in this environment."
			fi
		fi

	fi


  	DISABLEREPO=""
  	if [ -f /etc/yum.repos.d/atomic.repo ]; then
    		DISABLEREPO="--disablerepo=atomic"
  	fi


	  # Test X: download & install asl
	  if ! rpm --quiet -q asl; then
		 yum -y --disableexcludes=all install asl | tee -a $LOG
		 if [ ${PIPESTATUS[0]} -ge 1 ]; then
				echo
				echo "Error: Could not install ASL" |tee -a $LOG
				app_exit 1
		 fi
	  else
		 yum -y --disableexcludes=all upgrade asl | tee -a $LOG
		 if [ ${PIPESTATUS[0]} -ge 1 ]; then
				echo
				echo "Error: Could not upgrade ASL" |tee -a $LOG
				app_exit 1
		 fi

	  fi

	# Cpanel only
    	chown nobody.nobody /var/asl/data/msa
    	chown nobody.nobody /var/asl/data/audit
    	chown nobody.nobody /var/asl/data/suspicious

	if [ ! -d /etc/httpd/conf.d ]; then
	    mkdir /etc/httpd/conf.d
	    touch /etc/httpd/conf.d/00_mod_security.conf
	fi
	if [ ! -d /etc/httpd/modsecurity.d ]; then
	    mkdir /etc/httpd/modsecurity.d
	    touch /etc/httpd/modsecurity.d//modsecurity_crs_10_config.conf
	fi

}

function kernel_install {
	freespace_check "/boot" "70"
	# Test for a source kernel install
	if rpm -qa |grep ^kernel |grep -q `uname -r`; then
		INSTALL_KERNEL=1
	else
		INSTALL_KERNEL=0
		echo "Kernel mismatch detected. It does not appear that an rpm managed kernel is installed"
		echo "ASL kernel installation cannot continue."
		echo "  The kernel reported was " `uname -r`

	fi

	# real kernel installation starts here
	if [ -f /etc/sysconfig/kernel ] && [ $INSTALL_KERNEL -eq 1 ] ; then

		source /etc/sysconfig/kernel

		echo
		echo "Attempting ASL kernel installation " |tee -a $LOG
		echo

		echo "  Attempting to install ASL kernel"

                if [ "$DIST" == "el7" ]; then
			if [ $BETA -eq 1 ]; then
				yum --enablerepo=$KERNEL_CHANNEL-testing -y install kernel-asl | tee -a $LOG
			else
				yum --enablerepo=$KERNEL_CHANNEL -y install kernel-asl gradm | tee -a $LOG
			fi

			# boot once
			/usr/sbin/grub2-reboot 1

		else
			if [ "$UPDATEDEFAULT" == "yes" ]; then
				echo "  Disabling UPDATEDEFAULT in /etc/sysconfig/kernel temporarily"  |tee -a $LOG
				perl -p -i -e "s/UPDATEDEFAULT.*/UPDATEDEFAULT=no/" /etc/sysconfig/kernel
				RESTORE_UPDATEDEFAULT=1
			fi

			rpm --quiet -q kernel-asl && yum --enablerepo=$KERNEL_CHANNEL -y install kernel-asl gradm | tee -a $LOG
			yum --enablerepo=$KERNEL_CHANNEL -y install xtables-addons kmod-xtables-addons| tee -a $LOG
			sed -i "s/=kernel/=kernel-asl/g" /etc/sysconfig/kernel

			echo "  Configuring ASL kernel to boot in test mode." | tee -a $LOG
/sbin/grub --batch <<EOF
savedefault --default=0 --once
EOF

			echo
			echo
			echo



			if [ "$RESTORE_UPDATEDEFAULT" == "1" ]; then
				echo "  Restoring UPDATEDEFAULT in /etc/sysconfig/kernel" | tee -a $LOG
				perl -p -i -e "s/UPDATEDEFAULT.*/UPDATEDEFAULT=yes/" /etc/sysconfig/kernel
			fi

		fi

		# Detect network cards
		/sbin/ifconfig -a |awk '/eth/ {print $1}' > /asl-install-network-info
		cat /asl-install-network-info >> $LOG

		# Update xtables geoip data
        	rpm --quiet -q perl-Text-CSV_XS || yum -y install perl-Text-CSV_XS
		yum --enablerepo=$KERNEL_CHANNEL -y install xtables-addons | tee -a $LOG

		/var/asl/bin/xt_geoip-sync >/tmp/log 2>&1 &




	else
		echo "Skipping ASL kernel installation.." | tee -a $LOG
	fi

	# set the ASL firstboot flag
	perl -p -i -e "s/ASL_FIRSTBOOT.*/ASL_FIRSTBOOT=yes/" /etc/sysconfig/asl-firstboot
}

# Freespace check function
function freespace_check {

        FILESYSTEM=$1
        MINIMUM=$2

        SIZES=($(stat -L -f -c "%a %S" ${FILESYSTEM}))
        FREES=$((${SIZES[0]}*${SIZES[1]}))
        FREESMB=$(($FREES/1024/1024))

	echo "Freespace on $FILESYSTEM is: $FREESMB" >> $LOG

        if [ $FREESMB -lt $MINIMUM ]; then
                echo "  WARNING: in order to complete installation $FILESYSTEM will need at least $MINIMUM MB free."
                echo "  Currently: $FREESMB MB free"


                check_input "  Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

                if [ "$INPUTTEXT" == "no" ]; then
                        echo
                        echo "Exiting..."
                        echo
                        app_exit 1
                fi

                check_input "  Are you sure you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

                if [ "$INPUTTEXT" == "no" ]; then
                        echo
                        echo "Exiting..."
                        echo
                        app_exit 1
                fi

        fi

}


# Check input function
# 3 vars, the message to prompt, valid responses, and default response
# Example: check_input  "Some question (yes/no) " "yes|no"  "yes"

function check_input {
  message=$1
  validate=$2
  default=$3

  while [ $? -ne 1 ]; do
    echo -n "$message "
    read INPUTTEXT < $INSTALL_TTY
    if [ "$INPUTTEXT" == "" -a "$default" != "" ]; then
      INPUTTEXT=$default
      return 1
    fi
    echo $INPUTTEXT | egrep -q "$validate" && return 1
    echo "Invalid input"
  done

}

function posix_acl_check {
	ACL_TEST=/var/tmp/posix-acl-test
	touch $ACL_TEST
	echo -n "Checking for Filesystem POSIX ACL support: "
	/usr/bin/setfacl -m g:root:rw $ACL_TEST >/dev/null 2>&1
	if [ $? -ge 1 ]; then
		echo "FAILED"
		if [ ! $AUTO ]; then
			echo
			echo "WARNING: POSIX ACL filesystem support was not detected."
			echo "This is required in order to be able to use the Atomicorp"
			echo "T-WAF feature."
			echo
			echo "More information on enabling POSIX ACL's available here"
			echo "https://www.atomiccorp.com/wiki/index.php/ASL_prerequisites#POSIX_ACL_support"
			echo

			check_input "Continue with ASL configuration? (yes/no) [Default: no]" "yes|no" "no"

			if  [ "$INPUTTEXT" == "no" ]; then
				echo "Exiting...."
				exit
			fi
		fi


	else
		echo "PASS"
	fi

	rm -f $ACL_TEST
}


# Post asl web
function post_asl_web {
    IPADDRESS=`/sbin/ip addr | grep -v 'inet6' | grep -v '127\.[0-9]*\.[0-9]*\.[0-9]*' | sed -n -e 's/^ *inet \([0-9\.]*\).*$/\1/ p' | head -1`

    echo
    echo "ASL Web installation is complete."
    echo
    echo "To access ASL Web, point your browser to https://$IPADDRESS:30000 to log in."
    echo
    if [ ! $AUTO  ]; then
    	echo "Hit any key to continue"
    	read waiting < $INSTALL_TTY
    fi


}

# Post asl install actions
function post_asl_install {
	# prevent plesk key from being used if it gets restored
	if [ ! -f /etc/asl/.asl ]; then
		touch /etc/asl/.asl
	fi

	# Print out that the ASL repo is set up
	echo
	echo
	echo "The Atomic Secured Linux archive has now been installed and configured for your system"
	echo "The following channels are available:"
	echo "  asl-5.0 - [ENABLED]  - contains ASL 5.0 packages"
	echo "  asl-5.0-testing - [DISABLED]  - contains ASL 5.0 packages currently in QA "
	echo
	echo

	# Redundancy #1, ensure Version exists
	if [ ! -f /etc/asl/VERSION ]; then
cat << EOF > /etc/asl/VERSION
ASL_VERSION=0
APPINV_VERSION=0
CLAMAV_VERSION=0
GEOMAP_VERSION=0
GRSEC_VERSION=0
MODSEC_VERSION=0
OSSEC_VERSION=0
EOF
	fi

	# Redundancy #2, ensure db files exist
	if [ ! -f /etc/asl/disabled_signatures ]; then
  		touch /etc/asl/disabled_signatures
	fi

	if [ ! -f /etc/asl/whitelist ]; then
  		touch /etc/asl/whitelist
	fi

	# Redundancy #3, ensure localhost is set
	if ! grep -q 127.0.0.1.*localhost /etc/hosts; then
  		echo "127.0.0.1	localhost.localdomain	localhost" >> /etc/hosts
	fi


	if [ ! -f /etc/asl/config ]; then
		echo "Error: /etc/asl/config was not detected"
		echo
		app_exit 1
	fi

	if [ ! $AUTO ]; then
		check_input "Continue with ASL configuration? (yes/no) [Default: yes]" "yes|no" "yes"

		if  [ "$INPUTTEXT" == "no" ]; then
			echo "Exiting...."
			exit
		fi
	fi

	# set the basic config in /etc/asl/config
	ESCAPED_PASSWORD=$(echo $PASSWORD | sed -e 's/[\/&]/\\&/g')

	sed -i "s/\"USERNAME\"/\"$USERNAME\"/"  /etc/asl/config
	sed -i "s/\"PASSWORD\"/\"$ESCAPED_PASSWORD\"/"  /etc/asl/config

	# Install the tortix-release package
	rpm --quiet -q tortix-release || yum -y install tortix-release



	# Configure the system
	if [ ! $AUTO ]; then
		bash /var/asl/lib/modules/configuration_setup.sh
	else
		/var/asl/lib/modules/configuration_setup.sh auto

	fi


	# bugfix #xxx, clear invalid waf config. It will be corrected by fixmode later
	if [ -f /etc/httpd/conf.d/00_mod_security.conf ]; then
		rm -f /etc/httpd/conf.d/00_mod_security.conf

	fi


	touch /var/asl/data/{waf_classes,waf-rule-list,security-modules,updates-data,vulnerability-data,vulnerability-report.html,security-modules,webapp.db}

	echo "Preparing to update, this may take a moment" | tee -a $LOG

	/var/asl/bin/aum -uf

	COUNT=0
	while  [ ! -f /var/asl/rules/modsec/waf_rule_config ] ; do
		/var/asl/bin/aum -uf

		COUNT=`expr $COUNT + 1`
		if [ $COUNT -ge 4 ]; then
			#echo "Error: Could not complete installation."
			break
		fi
	done

	# Kernel
	source /etc/asl/config
	if [ "$KERNEL_CHANNEL" != "disabled" ]; then
		INPUTTEXT="yes"
		if [ ! $AUTO ]; then

			echo
			echo "The ASL kernel includes extensive advanced security features including"
			echo " * Real-time malware detection"
			echo " * Active kernel intrusion prevention"
			echo " * Advanced firewall capabilities"
			echo
			echo
			check_input "Install the ASL kernel? (yes/no) [Default: yes]" "yes|no" "yes"
		fi

		if [ "$INPUTTEXT" == "yes" ]; then
			kernel_install
		fi
	fi

	# Clear firewall rules
	if [ -f /etc/init.d/iptables ] ; then
		/etc/init.d/iptables stop >/dev/null 2>&1
	else
		service firewalld stop >/dev/null 2>&1
	fi

	# run a fix event
	/var/asl/bin/asl -s -f

	if [ -f /etc/init.d/asl-firewall ]; then
  		/etc/init.d/asl-firewall start  >/dev/null 2>&1
	fi


	# Scan the system for malware
	echo
	INPUTTEXT="yes"
	if [ ! $AUTO ]; then
		check_input "Would you like to scan the system for malware now? (yes/no): [Default: yes]" "yes|no" "yes"
	fi
	if  [ "$INPUTTEXT" == "yes" ]; then


	echo "Updating malware definitions..."
	if [ -f /usr/bin/freshclam ]; then
		/usr/bin/freshclam -d
	else
		echo
		echo "ERROR: malware update component not found!"
		echo "	Malware detection is broken. Unsupportable configuration"
		echo
	fi



	echo "Malware scanning has begun in the background"
	echo "a list of suspicious files will be written to:"
	echo "/root/asl-malware-scan.log"
	echo

    nice -n 20 clamscan --exclude-dir=^/var/ossec/  --exclude-dir=^/var/clamav --exclude-dir=^/var/lib/clamav --exclude-dir=^/etc/httpd/modsecurity.d/ --exclude-dir=^/usr/share/doc/clamav --exclude-dir=^/var/www/vhosts/.*/statistics/logs/ --exclude-dir=^/sys --exclude-dir=^/dev --exclude-dir=^/proc --exclude-dir=^/var/lib/spamassassin --exclude-dir=^/var/asl --exclude-dir=^/usr/share/w3af --exclude-dir=^/var/lib/openvas/plugins -i -r / > /root/asl-malware-scan.log 2>/dev/null &

	fi

	if rpm --quiet -q asl-web ; then
		post_asl_web
	fi

	smoketest | tee -a $LOG

	# Re-enable disabled repos
	if [ $ALT_REPO_DISABLED -ge 1 ]; then
	    for reponame in $ALT_REPO; do
	        /usr/bin/yum-config-manager --enable $reponame > /dev/null

	    done
	fi


	echo "Installation completed" >> $LOG

	if [ -f /etc/asl/tortix.key ]; then
	    echo "Your login information for the ASL Support Portal is:"
	    echo
	    echo "Username: $USERNAME"
	    echo "Password: $PASSWORD"
	    echo
	    echo "The support portal is located at https://atomicorp.com/support/support-portal.html"
	fi


	if [ "$KERNEL_CHANNEL" != "disabled" ]; then
		echo
		echo
		echo "Please reboot your server to complete the installation process."
		echo
		echo
	fi



}

function smoketest {
    RED='\033[1;31m'
    GREEN='\033[1;32m'
    NC='\033[0m'

    # Smoketest simple RFI for WAF
    echo "Running simple smoketest for Web Application Firewall..."
    # CMD= echo `curl -I -s -L 'http://127.0.0.1/foo.php?bar=http://wee.example.com/bad' |grep -i '403'`
    # echo $CMD
    if [[ `wget --server-response http://127.0.0.1/foo.php?foo=http://wee.example.com/bad 2>&1 | awk '/^  HTTP/{print $2}'` != '403' ]]; then
        echo -e "   WAF Smoketest: RFI                                        [${GREEN}FAIL${NC}]"
    else
        echo -e "   WAF Smoketest: RFI                                        [${GREEN}PASS${NC}]"
    fi
}

clear
echo
echo "Atomic Secured Linux Installer (v$INSTALLER_VER)"
echo "Further Documentation is available at: "
echo "https://wiki.atomicorp.com/wiki/index.php/ASL_installation"
echo
echo "Support: support@atomicorp.com"


if [ ! $AUTO ]; then

echo
echo "Hit any key to view the License agreement, or Ctrl-C to exit"
echo
read -n 1  < $INSTALL_TTY


cat << EOF | less -e -M -Ps"Press any key to view the next page"
STANDARD TERMS AND AGREEMENT


1. DEFINITIONS. Capitalized terms will have the
meanings set forth in this Section 1, or in the
section where they are first used.

1.1 "Access Protocols" means the passwords, access codes,
technical specifications, connectivity standards or protocols, or
other relevant procedures, as may be necessary to allow Customer
or any Authorized Users to access the Licensed Software.

1.2 "Authorized User" means each of Customer's employees, agents, and
independent contractors who are authorized to access the Licensed
Software pursuant to Customer's rights under this Agreement.

1.3 "Company" means Atomic Corporate Industries, Inc.

1.4 "Licensed Software" means the  software identified in any Order
Form that allows Authorized Users to access certain features and functions
through the Customer Environment.

1.5 "Customer" means the customer identified on the Order Form.

1.6 "Customer Content" means any content and information provided or
submitted by, or on behalf of, Customer or its Authorized Users for
use with the Services.

1.7 "Customer Environment" means the self-hosted (or third party hosted)
environment owned or controlled by Customer in which the Licensed
Software is deployed, as approved by Company. The Customer Environment
must meet the minimum specifications identified in writing by Company.

1.8 "Documentation" means the technical materials provided by Company
to Customer in hard copy or electronic form describing the use and
operation of the Licensed Software.

1.9 "Effective Date" means the date of last signature on the
first Order Form signed by the parties.

1.10 "Intellectual Property Rights" means any and all now known or
hereafter existing (a) rights associated with works of authorship,
including copyrights, mask work rights, and moral rights; (b) trademark
or service mark rights; (c) trade secret rights; (d) patents, patent
rights, and industrial property rights; (e) layout design rights,
design rights, and other proprietary rights of every kind and
nature other than trademarks, service marks, trade dress, and
similar rights; and (f) all registrations, applications, renewals,
extensions, or reissues of the foregoing, in each case in any
jurisdiction throughout the world.

1.11 "Licensed Material" means results, reports,
materials and documentation made available to Customer
as part of the Services.

1.12 "Order Form" means an order form or proposal
that is signed by both parties and references these
terms and conditions.

1.13 "Professional Services" means professional services
provided by Company to Customer as described in any Order
Form (as may be further elaborated in any statement of work),
including training and configuration services.

1.14 "Services" means any services provided by Company to
Customer under this Agreement as set forth in an Order Form,
including, but not limited to, provision of the Licensed
Software and Professional Services.

2. PROVISION OF SERVICES

2.1 Self-Hosted License. Subject to Customer's payment of
the fees set forth in the Order Form or any applicable SOW(s)
("Fees"), Company hereby grants to Customer a non-exclusive,
non-transferable, non-sublicenseable right and license during
the License Term set forth on the applicable Order Form (i) to
install and operate the Licensed Software as identified in an
Order Form in the Customer Environment solely in accordance with
applicable, standard Documentation provided by Company; and (ii)
to permit Authorized Users to access the Licensed Software solely
for Customer's internal business purposes. Customer will be and is
solely responsible for obtaining any third party licenses or consents
relating to Customer's data or Customer's integration or interoperation
of any Licensed Software with third party products or services not
provided by Company. Customer acknowledges and agrees that Company
shall not be liable for any down-time, loss of data or business,
corrupted, intelligible, garbled, deleted, lost or otherwise destroyed
data that is/was stored in the Customer Environment, or any other security
breaches attributable to the Customer Environment and/or the third-party service
provider(s) that own or control the Customer Environment.

2.2 Documentation License. Subject to the terms and conditions
of this Agreement and Customer's payment of Fees, Company hereby
grants to Customer a non-exclusive, non-transferable, non-sublicenseable
right and license during the Term to make copies of the Documentation
provided by Company solely for use by individual employees, agents, or
contractors of Customer in connection with the exercise of rights granted
in Section 2.1. Customer acknowledges that no right is granted to modify, adapt,
translate, publicly display, publish, create derivative works or distribute the
Documentation.

2.3 Support Services. Company will exercise commercially
reasonable efforts to (a) provide support for the use of
the Licensed Software to Customer in accordance with the terms
of the Order Form, and (b) keep the Licensed Software operational
and available to Customer, in each case in accordance with its
standard policies and procedures.

2.4 Delivery. As soon as commercially practicable
after the Effective Date, Company shall deliver to
Customer one (1) copy of the Licensed Software and the
Documentation for use by Customer in exercising its rights
under the licenses granted in Section 2.1.  Notwithstanding
any provision under a separate SOW which may require Company
to perform certain services in the nature of installation of
the Licensed Software or configuration of Customer's computers,
networks or other systems, for purposes of this Addendum delivery
shall be deemed complete upon receipt by Customer of media upon
which the Licensed Software and Documentation are digitally
stored (the "Delivery Date").

3. INTELLECTUAL PROPERTY

3.1 Ownership. The Licensed Software, Licensed Materials
and Documentation, and all worldwide Intellectual Property
Rights in each of the foregoing, are the exclusive property
of Company and its suppliers. All rights in and to the Licensed
Software and Documentation not expressly granted to Customer
in this Agreement are reserved by Company and its suppliers.
Except as expressly set forth herein, no express or implied
license or right of any kind is granted to Customer regarding
the Licensed Software, Documentation, or any part thereof.

3.2 Restrictions. Customer will not, and will not permit
any Authorized User or other party to: (a) allow any
third party to access the Licensed Software, Licensed
Material or Documentation, except as expressly allowed herein;
(b) modify, adapt, alter or translate the Licensed Software,
Licensed Material or Documentation; (c) sublicense, lease,
sell, resell, rent, loan, distribute, transfer or otherwise
allow the use of the Licensed Software or Documentation for the
benefit of any unauthorized third party; (d) reverse engineer, decompile,
disassemble, or otherwise derive or determine or attempt to
derive or determine the source code (or the underlying ideas, algorithms,
structure or organization) of the Licensed Software, except as
permitted by law; (e) interfere in any manner with the operation of
the Licensed Software or the hardware and network used to operate
the Licensed Software; (f) modify, copy or make derivative works based
on any part of the Licensed Software or Documentation; (g) access or
use the Licensed Software to build a similar or competitive product
or service; (h) attempt to access the Licensed Software through
any unapproved interface; or (i) otherwise use the Licensed Software,
Licensed Material, or Documentation in any manner that exceeds the
scope of use permitted under Section 3.1 or in a manner inconsistent
with applicable law, the Documentation, or this Agreement. Customer
acknowledges and agrees that the Licensed Software will not be used,
and are not licensed for use, in connection with any of Customer's
time-critical or mission-critical functions. Customer will not remove,
alter, or obscure any proprietary notices (including copyright and
trademark notices) of Company or its licensors on the Licensed
Material or any copies thereof.

3.3 Open Source Software. Certain items of software may be
provided to Customer with the Licensed Software and are
subject to "open source" or "free software" licenses ("Open Source
Software"). Some of the Open Source Software is owned by third
parties. The Open Source Software is not subject to the terms and
conditions of Sections 2.1 or 10. Instead, each item of Open Source
Software is licensed under the terms of the end-user license that
accompanies such Open Source Software. Nothing in this Agreement
limits Customer's rights under, or grants Customer rights that
supersede, the terms and conditions of any applicable end user
license for the Open Source Software. If required by any license
for particular Open Source Software, Company makes such Open Source
Software, and Company's modifications to that Open Source Software, available
by written request at the notice address specified below.

3.4 Feedback. Customer hereby grants to Company a
royalty-free, worldwide, transferable, sublicensable,
irrevocable, perpetual license to use or incorporate into the
Services any suggestions, enhancement requests, recommendations or other
feedback provided by Customer, including Authorized Users, relating
to the Services. Company will not identify Customer as the source of
any such feedback.

4. FEES AND EXPENSES; PAYMENTS

4.1 Fees. In consideration for the license rights
granted to Customer and the Services performed by
Company under this Agreement, Customer will pay to
Company the Fees. Except as otherwise provided in
the Order Form, all Fees are billed at the end of the
month due and payable within thirty (30) days of the
date of the invoice. Company reserves the right to modify the
Fees payable hereunder upon written notice to Customer at least
[ninety (90) days] prior to the end of the then-current term.
Company will be reimbursed only for expenses that are expressly
provided for in an Order Form or SOW or that have been approved
in advance in writing by Customer, provided Company has furnished
such documentation for authorized expenses as Client may reasonably request.
Company reserves the right (in addition to any other
rights or remedies Company may have) to terminate this Agreement
if any Fees are more than thirty (30) days overdue until such amounts
 are paid in full. Customer will maintain complete, accurate and up-to-date
Customer billing and contact information at all times.

4.2 Taxes. The Fees are exclusive of all applicable
sales, use, value-added and other taxes, and all
applicable duties, tariffs, assessments, export and
import fees, or other similar charges, and Customer
will be responsible for payment of all such taxes (other than
taxes based on Company's income), fees, duties, and charges and any related
penalties and interest, arising from the payment of the fees, the
provision of the Services, or the license of the Licensed Software
to Customer. Customer will make all payments of Fees to Company free
and clear of, and without reduction for, any withholding taxes; any such taxes
imposed on payments of Fees to Company will be Customer's sole
responsibility, and Customer will provide Company with official
receipts issued by the appropriate taxing authority, or such other evidence
as the Company may reasonably request, to establish that such taxes have
been paid.

4.3 Interest. Any amounts not paid when due will
bear interest at the rate of one and one half percent
(1.5%) per month, or the maximum legal rate if less, from
the due date until paid.

5. CUSTOMER CONTENT AND RESPONSIBILITIES

5.1 License; Ownership. Customer is solely responsible
for any and all obligations with respect to the accuracy,
quality and legality of Customer Content.  Customer will
obtain all third party licenses, consents and permissions
needed for Company to use the Customer Content to provide
the Services.  Without limiting the foregoing, Customer will
be solely responsible for obtaining from third parties all
necessary rights for Company to use the Customer Content submitted
by or on behalf of Clients for the purposes set forth in this Agreement.
Customer grants Company a non-exclusive, worldwide, royalty-free and
fully paid license during the Term (a) to use the Customer Content
as necessary for purposes of providing and improving the Services,
(b) to use the Customer trademarks, service marks, and logos as
required to provide the Services, and (c) use the Customer Content
in an aggregated and anonymized form to: (i) improve the Services and
Company's related products and services; (ii) provide analytics and
benchmarking services; and (iii) generate and disclose statistics
regarding use of the Services, provided, however, that no Customer-only
statistics will be disclosed to third parties without Customer's consent.
The Customer Content, and all worldwide Intellectual Property Rights in
it, is the exclusive property of Customer. All rights in and to the Customer
Content not expressly granted to Company in this Agreement
are reserved by Customer.

5.2 Customer Warranty. Customer represents and warrants
that any Customer Content will not (a) infringe any copyright,
trademark, or patent; (b) misappropriate any trade secret; (c) be
deceptive, defamatory, obscene, pornographic or unlawful; (d) contain
any viruses, worms or other malicious computer programming codes
intended to damage Company's system or data; and (e) otherwise violate
the rights of a third party. Company is not obligated to back up any
Customer Content; the Customer is solely responsible for creating backup
copies of any Customer Content at Customer's sole cost and expense.
Customer agrees that any use of the Licensed Software contrary to or
in violation of the representations and warranties of Customer in this
Section 5.2 constitutes unauthorized and improper use of the Licensed
Software.

5.3 Customer Responsibility for Data and Security. Customer and
its Authorized Users will have access to the Customer Content and
will be responsible for all changes to and/or deletions of Customer
Content and the security of all passwords and other Access Protocols
required in order the access the Licensed Software. Customer will
have the ability to export Customer Content out of the Licensed Software
and is encouraged to make its own back-ups of the Customer Content.
Customer will have the sole responsibility for the accuracy, quality,
integrity, legality, reliability, and appropriateness of all Customer Content.

6. PROFESSIONAL SERVICES. Where the parties have agreed to
Company's provision of Professional Services, the details of
such Professional Services will be set out in an Order Form or a
mutually executed statement of work ("SOW").  The Order Form or SOW,
as applicable, will include: (a) a description of the Professional Services;
(b) the schedule for the performance of the Professional Services; and
(c) the Fees applicable for the performance of the Professional Services.
Each Order Form or SOW, as applicable, will incorporate the terms and
conditions of this Agreement.  To the extent that a conflict arises between
the terms and conditions of an Order Form or SOW and the terms of this
Agreement, the terms and conditions of this Agreement will govern, except
to the extent that the Order Form or SOW, as applicable, expressly
states that it supersedes specific language in the Agreement.

7. WARRANTIES AND DISCLAIMERS

7.1 Limited Warranty. Company warrants, for the benefit
of Company only, that the Licensed Software, when used in the
Customer Environment, will conform in all material respects
to the Documentation for a period of ninety (90) days after the
Delivery Date ("Warranty Period"), provided that such warranty
will not apply to failures to conform to the Documentation
to the extent such failures arise, in whole or in part, from any
modification of the Licensed Software by Customer or any third
party or any combination of the Licensed Software with software,
hardware or other technology not provided by Company under this
Agreement (except to the extent such combination is expressly
contemplated in the Documentation as required for ordinary operation
of the Licensed Software). Provided that Customer submits written
notice to Company of any such breach of warranty during the Warranty
Period, within thirty (30) days of such breach, Company will, as
Customer's sole and exclusive remedy, for any breach of the foregoing,
repair or replace the Licensed Software so that it conforms in all material
respects to the Documentation or, at Company's option, refund the fees paid
by Customer for the Services which gave rise to the breach.

7.2 Disclaimer. THE LIMITED WARRANTY SET FORTH IN SECTION 7.1
IS MADE FOR THE BENEFIT OF CUSTOMER ONLY. EXCEPT AS EXPRESSLY
PROVIDED IN THIS SECTION 7.1, AND TO THE MAXIMUM EXTENT PERMITTED
BY APPLICABLE LAW, THE SERVICES, LICENSED MATERIAL AND DOCUMENTATION
ARE PROVIDED "AS IS," AND COMPANY MAKES NO (AND HEREBY DISCLAIMS ALL)
OTHER WARRANTIES, REPRESENTATIONS, OR CONDITIONS, WHETHER WRITTEN, ORAL,
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
WARRANTIES OF SATISFACTORY QUALITY, COURSE OF DEALING, TRADE USAGE OR
PRACTICE, SYSTEM INTEGRATION, DATA ACCURACY, MERCHANTABILITY, TITLE,
NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. COMPANY DOES
NOT WARRANT THAT ALL ERRORS CAN BE CORRECTED, OR THAT OPERATION OF
THE LICENSED SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.

8. LIMITATION OF LIABILITY

8.1 Types of Damages. IN NO EVENT WILL EITHER PARTY BE
LIABLE TO THE OTHER PARTY FOR ANY INCIDENTAL, INDIRECT,
SPECIAL, CONSEQUENTIAL OR PUNITIVE DAMAGES, REGARDLESS OF THE
NATURE OF THE CLAIM, INCLUDING, WITHOUT LIMITATION, LOST PROFITS,
COSTS OF DELAY, ANY FAILURE OF DELIVERY, BUSINESS INTERRUPTION,
COSTS OF LOST OR DAMAGED DATA OR DOCUMENTATION, OR LIABILITIES TO
THIRD PARTIES ARISING FROM ANY SOURCE, EVEN IF A PARTY HAS BEEN ADVISED
OF THE POSSIBILITY OF SUCH DAMAGES.  THIS LIMITATION UPON DAMAGES AND
CLAIMS IS INTENDED TO APPLY WITHOUT REGARD TO WHETHER OTHER PROVISIONS
OF THIS AGREEMENT HAVE BEEN BREACHED OR HAVE PROVEN INEFFECTIVE.

8.2 Amount of Damages. THE MAXIMUM LIABILITY OF EITHER PARTY
ARISING OUT OF OR IN ANY WAY CONNECTED TO THIS AGREEMENT WILL
NOT EXCEED THE FEES PAID BY CUSTOMER TO COMPANY DURING THE TWELVE
(12) MONTHS PRECEDING THE ACT, OMISSION OR OCCURRENCE GIVING RISE
TO SUCH LIABILITY. IN NO EVENT WILL COMPANY'S SUPPLIERS HAVE ANY
LIABILITY ARISING OUT OF OR IN ANY WAY CONNECTED TO THIS AGREEMENT.
NOTHING IN THIS AGREEMENT WILL LIMIT OR EXCLUDE EITHER PARTY'S
LIABILITY FOR GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT OF A
PARTY OR ITS EMPLOYEES OR AGENTS OR FOR DEATH OR PERSONAL INJURY.

8.3 Basis of the Bargain. The parties agree that the limitations
of liability set forth in this Section 8 will survive and continue
in full force and effect despite any failure of consideration or
of an exclusive remedy. The parties acknowledge that the prices
have been set and the Agreement entered into in reliance upon
these limitations of liability and that all such limitations
form an essential basis of the bargain between the parties.


9. CONFIDENTIALITY

9.1 Confidential Information. "Confidential Information" means any
nonpublic information of a party (the "Disclosing Party"), whether
disclosed orally or in written or digital media, that is identified
as "confidential" or with a similar legend at the time of such disclosure
or that the receiving party (the "Receiving Party") knows or should
have known is the confidential or proprietary information of the
Disclosing Party. The Services, Documentation, and all enhancements
and improvements thereto will be considered Confidential Information
of Company.

9.2 Protection of Confidential Information. The Receiving
Party agrees that it will not use or disclose to any third
party any Confidential Information of the Disclosing Party,
except as expressly permitted under this Agreement. The
Receiving Party will limit access to the Confidential
Information to Authorized Users (with respect to Customer)
or to those employees who have a need to know, who have
confidentiality obligations no less restrictive than those
set forth herein, and who have been informed of the confidential
nature of such information (with respect to Company). In
addition, the Receiving Party will protect the Disclosing
Party's Confidential Information from unauthorized use, access,
or disclosure in the same manner that it protects its own
proprietary information of a similar nature, but in no event
with less than reasonable care. At the Disclosing Party's
request or upon termination or expiration of this Agreement,
the Receiving Party will return to the Disclosing Party or
destroy (or permanently erase in the case of electronic files)
all copies of the Confidential Information that the Receiving
Party does not have a continuing right to use under this Agreement,
and the Receiving Party will, upon request, certify to the Disclosing
Party its compliance with this sentence.

9.3 Exceptions. The confidentiality obligations set forth in
Section 9.2 will not apply to any information that (a) is at
the time of disclosure or becomes generally available to the
public through no fault of the Receiving Party; (b) is lawfully
provided to the Receiving Party by a third party free of any
confidentiality duties or obligations; (c) was already known
to the Receiving Party at the time of disclosure free of any
confidentiality duties or obligations; or (d) the Receiving
Party can demonstrate, by clear and convincing evidence, was
independently developed by employees and contractors of the
Receiving Party who had no access to the Confidential Information.
In addition, the Receiving Party may disclose Confidential
Information to the extent that such disclosure is necessary
for the Receiving Party to enforce its rights under this
Agreement or is required by law or by the order of a court
or similar judicial or administrative body, provided that
(to the extent legally permissible) the Receiving Party promptly
notifies the Disclosing Party in writing of such required
disclosure and cooperates with the Disclosing Party if the
Disclosing Party seeks an appropriate protective order.

10. INDEMNIFICATION

10.1 By Company. Company will defend at its expense any suit
brought against Customer, and will pay any settlement Company
makes or approves, or any damages finally awarded in such suit,
insofar as such suit is based on a claim by any third party
alleging that the Licensed Software infringes such third party's
patents, copyrights or trade secret rights under applicable laws
of any jurisdiction within the United States of America. If any
portion of the Licensed Software becomes, or in Company's opinion
is likely to become, the subject of a claim of infringement,
Company may, at Company's option: (a) procure for Customer the
right to continue using the Licensed Software; (b) replace the
Licensed Software with non-infringing software or services which
do not materially impair the functionality of the Licensed Software;
(c) modify the Licensed Software so that it becomes non-infringing;
or (d) terminate this Agreement and refund any unused prepaid Fees
for the remainder of the term then in effect, and upon such termination,
Customer will immediately cease all use of the Licensed Software and
Documentation. Notwithstanding the foregoing, Company will have no
obligation under this Section 10.1 or otherwise with respect to any
infringement claim based upon (i) any use of the Licensed Software
not in accordance with this Agreement or as specified in the Documentation;
(ii) any use of the Licensed Software in combination with other products,
equipment, software or data not supplied by Company; or (iii) any modification
of the Licensed Software by any person other than Company or its authorized
agents (collectively, the "Exclusions" and each, an "Exclusion"). This
Section 10.1 states the sole and exclusive remedy of Customer and the
entire liability of Company, or any of the officers, directors, employees,
shareholders, contractors or representatives of the foregoing, for
infringement claims and actions.

10.2 By Customer. Customer will defend at its expense
any suit brought against Company, and will pay any
settlement Customer makes or approves, or any damages
finally awarded in such suit, insofar as such suit is based on
a claim arising out of or relating to (a) an Exclusion, or
(b) Customer's breach or alleged breach of Sections 5.2.
This Section 10.2 states the sole and exclusive remedy of
Company and the entire liability of Customer, or any of the
officers, directors, employees, shareholders, contractors or
representatives of the foregoing, for the claims and actions
described herein.

10.3 Procedure. The indemnifying party's obligations
as set forth above are expressly conditioned upon
each of the foregoing: (a) the indemnified party will
promptly notify the indemnifying party in writing of any
threatened or actual claim or suit; (b) the indemnifying
party will have sole control of the defense or settlement
of any claim or suit; and (c) the indemnified party will
cooperate with the indemnifying party to facilitate the
settlement or defense of any claim or suit.


11. TERM AND TERMINATION

11.1 Term. This Agreement will begin on the Effective
Date and continue in full force and effect as long as
any Order Form and/or Statement of Work remains in
effect, unless earlier terminated in accordance with the
Agreement (the "Term"). Unless otherwise stated in the
applicable Order Form, the term of an Order Form will
begin on the effective date of the Order Form and continue
in full force and effect for one (1) year, unless earlier
terminated in accordance with the Agreement. Thereafter, the
Order Form will automatically renew for additional terms of
one (1) year unless either party gives written notice of non-renewal
to the other party at least [sixty (60) days] prior to the expiration
of the then-current term.  The term of an Order Form is referred
to herein as the "License Term".

11.2 Termination for Convenience.  Either party may
terminate this Agreement for convenience on sixty (60)
days' prior written notice to the other party. Customer
acknowledges and agrees that it will not receive a refund
of any Fees paid as of the date of termination.

11.3 Termination for Breach. Either party may
terminate this Agreement immediately upon notice
to the other party if the other party materially
breaches this Agreement, and such breach remains uncured
more than thirty (30) days after receipt of written
notice of such breach.

11.4 Effect of Termination. Upon termination or
expiration of this Agreement for any reason: (a)
all licenses granted hereunder will immediately terminate;
(b) promptly after the effective date of termination or
expiration, each party will comply with the obligations to
return all Confidential Information of the other party,
as set forth in the Section 9; and (c) any amounts owed
to Company under this Agreement will become immediately
due and payable. Sections 1, 3.2, 3.3, 3.5, 4, 7.2, 8, 9,
10, 11.3, 11.4, and 12 will survive expiration or termination
of this Agreement for any reason.


12. MISCELLANEOUS

12.1 Governing Law and Venue. This Agreement and any action related
thereto will be governed and interpreted by and under the laws of
the State of Delaware, without giving effect to any conflicts of
laws principles that require the application of the law of a
different jurisdiction. Customer hereby expressly consents to
the personal jurisdiction and venue in the state and federal
courts for New Castle County, Delaware for any lawsuit filed
there against Customer by Company arising from or related to
this Agreement. The United Nations Convention on Contracts for
the International Sale of Goods does not apply to this Agreement.

12.2 Export. Customer agrees not to export, reexport,
or transfer, directly or indirectly, any U.S. technical
data acquired from Company, or any products utilizing
such data, in violation of the United States export
laws or regulations.

12.3 Severability. If any provision of this Agreement
is, for any reason, held to be invalid or unenforceable,
the other provisions of this Agreement will remain
enforceable and the invalid or unenforceable provision
will be deemed modified so that it is valid and
enforceable to the maximum extent permitted by law.

12.4 Waiver. Any waiver or failure to enforce any
provision of this Agreement on one occasion will not
be deemed a waiver of any other provision or of such
provision on any other occasion.

12.5 No Assignment. Neither party will assign,
subcontract, delegate, or otherwise transfer
this Agreement, or its rights and obligations herein,
without obtaining the prior written consent of the
other party, and any attempted assignment, subcontract,
delegation, or transfer in violation of the foregoing
will be null and void; provided, however, that either party
may assign this Agreement in connection with a merger,
acquisition, reorganization or sale of all or substantially
all of its assets, or other operation of law, without any
consent of the other party. The terms of this Agreement will
be binding upon the parties and their respective successors
and permitted assigns.

12.6 Compliance with Law. Customer will always comply with all
international and domestic laws, ordinances, regulations, and
statutes that are applicable to its purchase and use of the
Services, Licensed Material and Documentation.

12.7 Force Majeure. Any delay in the performance of any duties
or obligations of either party (except the payment of Fees owed)
will not be considered a breach of this Agreement if such delay
is caused by a labor dispute, shortage of materials, fire,
earthquake, flood, or any other event beyond the control of such party,
provided that such party uses reasonable efforts, under the circumstances,
to notify the other party of the cause of such delay and to resume
performance as soon as possible.

12.8 Independent Contractors. Customer's relationship to Company is
that of an independent contractor, and neither party is an agent or
partner of the other. Customer will not have, and will not represent
to any third party that it has, any authority to act on behalf of Company.

12.9 Notices. All notices required or permitted under
this agreement must be delivered in writing, if to
Company, by emailing [INSERT EMAIL] and if to Customer
by emailing the Customer email address listed on the applicable
Order Form, provided, however, that with respect to any notices
relating to breaches of this agreement or termination, a copy of
such notice will also be sent in writing to the other party at
the address listed on the Order Form by courier, by certified or
registered mail (postage prepaid and return receipt requested), or
by a nationally-recognized express mail service. Each party may
change its email address and/or address for receipt of notice by
giving notice of such change to the other party.

12.10 Counterparts. This Agreement may be executed in one
or more counterparts, each of which will be deemed an
original and all of which will be taken together and deemed
to be one instrument.

12.11 Entire Agreement. This Agreement is the final,
complete and exclusive agreement of the parties with
respect to the subject matters hereof and supersedes and
merges all prior discussions between the parties with respect
to such subject matters. No modification of or amendment to
this Agreement, or any waiver of any rights under this Agreement,
will be effective unless in writing and signed by an authorized
signatory of Customer and the Company.


EOF

check_input  "Do you agree to these terms (yes/no) [Default: yes]" "yes|no"  "yes"

if [ $INPUTTEXT != "yes" ]; then
	echo "
	Exiting install, License was not accepted
	"  | tee -a $LOG
	app_exit 1
fi
echo "NOTICE: User accepted License" >> $LOG

fi


#echo
#posix_acl_check

echo



echo -n "Checking for free space:"
freespace_check "/var" "1000"
freespace_check "/usr" "500"
freespace_check "/tmp" "10"
freespace_check "/etc" "100"
echo " Done"

echo -n "Checking for memory requirements: "
memory=$(free |awk '/Mem:/ {print $2}')
if [ $memory -lt 900000 ]; then
	echo "Failed" | tee -a $LOG
	echo "	a minimuim of 1G of memory is required for ASL." | tee -a $LOG

	app_exit 1
else
	echo "PASS"
fi

echo -n "Checking sudo: "
/usr/bin/sudo true >/dev/null 2>&1
if [ $? -eq 0 ]; then
        echo PASS
else
        echo FAIL
        echo
        echo "Error: Sudo execution failed. " | tee -a $LOG
        echo
        /usr/bin/sudo true
        echo
        echo "Contact your Operating System provider for support."
        echo

        if [ $FREESMB -lt $MINIMUM ]; then
                echo "  WARNING: in order to complete installation $FILESYSTEM will need at least $MINIMUM MB free."
                echo "  Currently: $FREESMB MB free"


                check_input "  Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

                if [ "$INPUTTEXT" == "no" ]; then
                        echo
                        echo "Exiting..."
                        echo
                        app_exit 1
                fi

                check_input "  Are you sure you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

                if [ "$INPUTTEXT" == "no" ]; then
                        echo
                        echo "Exiting..."
                        echo
                        app_exit 1
                fi

                app_exit 1
        fi

fi



if [ -f /etc/yum.repos.d/asl.repo ]; then
	rm -f /etc/yum.repos.d/asl.repo
fi


# Check for 3rd party repos
ALT_REPO=$(yum -v -C repolist |awk -F: '/Repo-id/  {print $2}' |egrep -iv "^ (asl-|atomic|base|extras|updates|tortix|cloudlinux|epel|plesk|rhel-6|EA4|r1soft|quantum|zabbix|PLESK|mysql|percona|cpanel-addons-production-feed|rack|mariadb|rhel-7|rhel-server|rhel-ha|rhel-rs|rhel-sjis)")
RETVAL=$?
if [ $RETVAL -lt 1 ]; then
	echo
	echo
	echo "WARNING: 3rd party yum repositories could conflict during ASL configuration." | tee -a $LOG
	echo "The following repositories were detected:" | tee -a $LOG
	echo $ALT_REPO | tee -a $LOG
	echo
	echo "Recommendation: Temporarily disable these repositories before continuing the installation.  "
	echo "                Or if you know these are mirrors of official distributin repositories, and not"
	echo "                and not a third party copy or third party repo you may continue.  Please know "
	echo "                that standard support does not cover installation when third party repos are enabled."
	echo

	if [ ! $AUTO ]; then
		if [ -f /usr/bin/yum-config-manager ]; then

			echo
			echo "ASL can attempt to disable these repos in order to assist you in continuing the installation."
			echo "			These will be re-enabled after the installation has copleted."
			echo

			check_input "  Do you wish to allow ASL to disable these repos? (yes/no) [Default: yes]" "yes|no" "yes"
			if [ "$INPUTTEXT" == "yes" ]; then
				ALT_REPO_DISABLED=1
				for reponame in $ALT_REPO; do
					echo "Disabling: $reponame"
					/usr/bin/yum-config-manager --disable $reponame > /dev/null
				done
			fi

		else

			check_input "  Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

			if [ "$INPUTTEXT" == "no" ]; then
				echo
				echo "Exiting..."
				echo
				app_exit 1
			fi

			check_input "  Are you sure you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

			if [ "$INPUTTEXT" == "no" ]; then
				echo
				echo "Exiting..."
				echo
				app_exit 1
			fi

		fi

	fi

fi

# Check for non-standard mysql
#M_LIST=$(rpm -qa |grep -i ^mysql |egrep -v "mysql-|^mysqltuner|^mysqlclient|^MySQL-")
#RETVAL=$?
#if [ $RETVAL -lt 1 ]; then
#	echo
#	echo
#	echo "WARNING: 3rd party mysql packages detected. ASL is supported with the" | tee -a $LOG
#	echo "official version of MySQL provided by Redhat, Centos and Atomicorp for"| tee -a $LOG
#	echo "that platform and distribution. Installation may not be possible on "| tee -a $LOG
#	echo "this system."| tee -a $LOG
#	echo
#        echo "The following packages were detected:"| tee -a $LOG
#        echo $M_LIST| tee -a $LOG
#        echo
#        echo
#
#	if [ ! $AUTO ]; then
#		check_input "  Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"
#		if [ "$INPUTTEXT" == "no" ]; then
#			echo
#			echo "Exiting..."
#			echo
#			app_exit 1
#		fi
#
#		check_input "  Are you sure you wish to continue? (yes/no) [Default: no]" "yes|no" "no"
#
##		if [ "$INPUTTEXT" == "no" ]; then
#			echo
#			echo "Exiting..."
##			echo
#			app_exit 1
#		fi
#	fi
#
#	echo "WARNING: 3rd party Mysql detected, user accepted risk." >> $LOG
#
#
#fi

if [ -d /etc/csf ]; then
	echo
	echo
	echo "WARNING: Configserver (CSF) detected. ASL does not support CSF."
	echo "CSF or other 3rd party WAF / Firewall management tools should be removed"
	echo "before installing ASL."
	echo
	echo


	if [ ! $AUTO ]; then
		check_input "  Would you like to remove csf? (yes/no) [Default: yes]" "yes|no" "yes"
		if [ "$INPUTTEXT" == "yes" ]; then
			if [ -f /etc/csf/uninstall.sh ]; then
				/etc/csf/uninstall.sh
			fi
		else
			check_input "  Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"
			if [ "$INPUTTEXT" == "no" ]; then
				echo
				echo "Exiting..."
				echo
				app_exit 1
			fi

			check_input "  Are you sure you wish to continue? (yes/no) [Default: no]" "yes|no" "no"

			if [ "$INPUTTEXT" == "no" ]; then
				echo
				echo "Exiting..."
				echo
				app_exit 1
			fi


		fi
	fi

	echo
	echo "WARNING: CSF detected, user accepted risk " >> $LOG
	echo

fi

echo
echo -n "Checking for core updates: "
Y_LIST=$(yum list updates |wc -l)
if [ $Y_LIST -gt 50 ]; then
	echo "Pending updates FAIL (count: $Y_LIST)" >> $LOG

	echo FAIL | tee -a $LOG
	echo  | tee -a $LOG
	echo "A test using the yum updater on the system indicated that it is significantly out of date. ($Y_LIST updates pending)" | tee -a $LOG
	echo "This environment may be so out of date that it will not be supportable." | tee -a $LOG
	echo | tee -a $LOG
	echo "Recommendation: Halt the installation, and investigate the unapplied Operating System patches to the system using the command:" | tee -a $LOG
	echo "		yum list updates" | tee -a $LOG
	echo | tee -a $LOG

	if [ ! $AUTO ]; then
		check_input "  This environment is UNSUPPORTED. Do you wish to continue? (yes/no) [Default: no]" "yes|no" "no"
		if [ "$INPUTTEXT" == "no" ]; then
			echo
			echo "Exiting..."
			echo
			app_exit 1
		fi
	fi

	echo
	echo
	echo
	echo "WARNING: Pending updates, user accepted risk " >> $LOG

else
	echo "OK"
	echo "Pending updates OK (count: $Y_LIST)" >> $LOG
fi

echo -n "Performing Basic environment checks: " | tee -a $LOG



echo | tee -a $LOG



# Main
if [ ! $AUTO ]; then
	CONFIGURED=no
fi

if [ ! -f /var/asl/bin/asl ]; then
        if [ -f /etc/asl/config ]; then

		mv /etc/asl/config /etc/asl/config.preupgrade
        fi

fi

if [ -f /etc/asl/config ] ; then
  	source /etc/asl/config
fi


if [ "$CONFIGURED" != "yes" ]; then


  # ---------  from tortix.key
  if [ -f /etc/asl/tortix.key ] && [ -s /etc/asl/tortix.key ]; then
  	TC_TARGET="updates.atomicorp.com/channels/rules/plesk/README"
	STEXT=`base64 -d /etc/asl/tortix.key`
	USERNAME=$(php -r "\$z = unserialize('"$STEXT"'); echo \$z[\"login\"] ; ")
	PASSWORD=$(php -r "\$z = unserialize('"$STEXT"'); echo \$z[\"pass\"] ; ")

	if [ "$USERNAME" == "" ]; then
		echo "	Error: Username was empty. (Encoding error)"
		app_exit 1
	fi

	if [ "$PASSWORD" == "" ]; then
		echo "	Error: Password field was empty. (Encoding error)"
		app_exit 1
	fi

	export USERNAME
	echo "Username: $USERNAME" >> $LOG
  # ---------  from stdin
  else
    	TC_TARGET="updates.atomicorp.com/channels/asl-3.0/README"
	echo -n "Enter subscription Username: " | tee -a $LOG
	read USERNAME < $INSTALL_TTY
	export USERNAME
	echo "Username: $USERNAME" >> $LOG

	if [ "$USERNAME" == "" ]; then
	  echo "Exiting: Username is blank. " | tee -a $LOG
	  echo
	  app_exit 1
	fi

	PASSCONFIRMED=0
	failed=0

	while [ $PASSCONFIRMED -lt 1 ]; do
	  if [ $failed -gt 2 ]; then
	    echo "Exiting: too many failed attempts." |tee -a $LOG
	    echo
	    app_exit 1
	  fi

	  echo -n "Enter Subscription Password: "
	  unset PASSWORD
	  read -sr PASSWORD < $INSTALL_TTY
	  #      while IFS= read -r -s -n1 pass <$INSTALL_TTY ; do
	  #              if [[ -z $pass ]]; then
	  #                      echo
	  #                      break
	  #              else
	  #                      echo -n '*'
	  #                      PASSWORD+=$pass
	  #              fi
	  #      done

	  echo


      if [ "$PASSWORD" == "" ]; then
        echo "Exiting: Password is blank..." | tee -a $LOG
        echo
        app_exit 1
      fi

      unset PASSWORD2
      echo -n "Re-Enter Subscription Password: "
	  read -sr PASSWORD2 < $INSTALL_TTY
        #while IFS= read -r -s -n1 pass <$INSTALL_TTY; do
        #        if [[ -z $pass ]]; then
        #                echo
        #                break
        #        else
        #                echo -n '*'
        #                PASSWORD2+=$pass
        #        fi
        #done
	  echo

      if [ "$PASSWORD" == "$PASSWORD2" ]; then
        PASSCONFIRMED=1
      else
        failed=$(( $failed + 1 ))
        echo "Sorry, passwords do not match." | tee -a $LOG
        echo
      fi
    done
  fi
fi

# Placeholder
#if [ -d /etc/asl ]; then
#	touch /etc/asl/tortix.key
#fi

ENCPASSWORD=$(rawurlencode $PASSWORD)


#TEST_CREDENTIALS=$($GET -nv https://$USERNAME:$ENCPASSWORD@www.atomicorp.com/channels/asl-3.0/README -O -  2>&1)
TEST_CREDENTIALS=$($GET -nv https://$USERNAME:$ENCPASSWORD@$TC_TARGET -O - 2>&1)

echo -n "Verifying account: " | tee -a $LOG
if [ "$TEST_CREDENTIALS" == "Authorization failed." ]; then
  echo " Failed" | tee -a $LOG
  echo
  echo "   ERROR: ASL Username/Password credentials are incorrect or this license has expired." | tee -a $LOG
  echo "   For more information, please see this FAQ:" | tee -a $LOG
  echo "   https://wiki.atomicorp.com/wiki/index.php/ASL_FAQ#HTTP_Error_401:_Authorization_Required_Trying_other_mirror" | tee -a $LOG
  echo
  app_exit 1
else
  echo "  Passed" | tee -a $LOG
fi

if [ -f /etc/system-release ]; then
	RELEASE_FILE=/etc/system-release
elif [ -f /etc/redhat-release ] ; then
	RELEASE_FILE=/etc/redhat-release
elif [ -f /etc/openvz-release ]; then
	RELEASE_FILE=/etc/openvz-release
elif [ -f /etc/virtuozzo-release ]; then
	RELEASE_FILE=/etc/openvz-release
else
	echo
  	echo "Error: /etc/redhat-release was not detected" | tee -a $LOG
	echo
	app_exit 1

fi

RELEASE=`cat $RELEASE_FILE | awk -F\( '{print $1}'`
echo "Release is: $RELEASE" >> $LOG


# EL5
if egrep -q "release 5|release 2011" $RELEASE_FILE ; then
  DIST="el5"
  DIR=centos/5
# EL6
elif egrep -q "release 6|release 2012" $RELEASE_FILE ; then
  DIST="el6"
  DIR=centos/6
# EL7
elif egrep -q "release 7" $RELEASE_FILE ; then
  	DIST="el7"
  	DIR=centos/7
else
  echo "Error: Unable to determine distribution type. Please send the contents of $RELEASE_FILE to support@atomicorp.com" | tee -a $LOG
  app_exit 1
fi

if [ ! -f /usr/bin/yum ]; then
	echo
  	echo "Error: Yum was not detected. Contact your provider for support." | tee -a $LOG
  	echo
	app_exit 1
else
  YUM=1
fi


## yum, make sure yum is up to date
echo -n "Ensuring yum is up to date: " | tee -a $LOG
/usr/bin/yum -y upgrade yum >> $LOG 2>&1
echo "Done" | tee -a $LOG

## check for perl (minimal installs)
echo -n "Checking for perl: " | tee -a $LOG
if  [ ! -f /usr/bin/perl ]; then
  /usr/bin/yum -y install perl >> $LOG 2>&1|| app_exit 1
fi
echo "Done" | tee -a $LOG

# Make sure selinux is as off as we can make it
if [ -x /usr/sbin/setenforce ]; then
  /usr/sbin/setenforce 0 >/dev/null 2>&1
  if [ -f /etc/sysconfig/selinux ]; then
    /usr/bin/perl -p -i -e "s/SELINUX=.*/SELINUX=disabled/g" /etc/sysconfig/selinux
  fi
  if [  -f /etc/selinux/config ]; then
    /usr/bin/perl -p -i -e "s/SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
  fi
fi

echo -n "Installing the Atomic GPG key: " |tee -a $LOG
if [ !  -f /etc/pki/rpm-gpg/RPM-GPG-KEY.art.txt ]; then
  	if [ ! -d /etc/pki/rpm-gpg ]; then
    		mkdir -p /etc/pki/rpm-gpg/
  	fi
  	wget -q https://www.atomicorp.com/RPM-GPG-KEY.art.txt -O /etc/pki/rpm-gpg/RPM-GPG-KEY.art.txt   >> $LOG 2>&1
	RETVAL=$?
	if [ ! "$RETVAL" = 0 ]; then
        	echo FAIL
		echo
                echo "  Could not download the Legacy Atomicorp gpg key"
                echo
                exit 1

	fi
	rm -f RPM-GPG-KEY.art.txt
fi
echo "OK" | tee -a $LOG
/bin/rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY.art.txt

if [ !  -f /etc/pki/rpm-gpg/RPM-GPG-KEY.atomicorp.txt ]; then
        if [ ! -d /etc/pki/rpm-gpg ]; then
        	mkdir -p /etc/pki/rpm-gpg/
        fi
        wget -q https://www.atomicorp.com/RPM-GPG-KEY.atomicorp.txt -O /etc/pki/rpm-gpg/RPM-GPG-KEY.atomicorp.txt   >> $LOG 2>&1
	RETVAL=$?
	if [ ! "$RETVAL" = 0 ]; then
        	echo FAIL

        	wget https://www.atomicorp.com/RPM-GPG-KEY.atomicorp.txt

		echo
        	echo "  Could not download the Atomicorp gpg key"
		echo
		exit 1
	fi

fi
/bin/rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY.atomicorp.txt


if [ ! -d /etc/asl ]; then
	mkdir /etc/asl
fi


cat  << EOF > /etc/yum.repos.d/asl.repo
[asl-4.0]
name=Atomicorp - $releasever - Atomic Secured Linux 4.0
mirrorlist=file:///etc/asl/asl-4.0-mirrorlist
priority=1
enabled=1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY.atomicorp.txt

gpgcheck=1
$KERNEL

[asl-4.0-testing]
name=Atomicorp - $releasever - Atomic Secured Linux 4.0 (Testing)
mirrorlist=file:///etc/asl/asl-4.0-testing-mirrorlist
priority=1
enabled=0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY.atomicorp.txt
gpgcheck=1
$KERNEL
EOF


cat << EOF > /etc/asl/asl-4.0-mirrorlist
https://$USERNAME:$ENCPASSWORD@www4.atomicorp.com/channels/asl-4.0/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www5.atomicorp.com/channels/asl-4.0/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www6.atomicorp.com/channels/asl-4.0/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www7.atomicorp.com/channels/asl-4.0/$DIR/$ARCH
EOF

cat << EOF > /etc/asl/asl-4.0-testing-mirrorlist
https://$USERNAME:$ENCPASSWORD@www4.atomicorp.com/channels/asl-4.0-testing/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www5.atomicorp.com/channels/asl-4.0-testing/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www6.atomicorp.com/channels/asl-4.0-testing/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www7.atomicorp.com/channels/asl-4.0-testing/$DIR/$ARCH
EOF

cat << EOF > /etc/asl/tortix-mirrorlist
https://$USERNAME:$ENCPASSWORD@www4.atomicorp.com/channels/tortix/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www5.atomicorp.com/channels/tortix/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www6.atomicorp.com/channels/tortix/$DIR/$ARCH
https://$USERNAME:$ENCPASSWORD@www7.atomicorp.com/channels/tortix/$DIR/$ARCH
EOF


# Begin install
if [ -d /usr/local/directadmin ] ; then
   echo "  DirectAdmin detected..." | tee -a $LOG
   DIRECTADMIN=1
   SOURCEINSTALL=1
   if [ -f /usr/sbin/httpd ] ; then
     HTTPD=/usr/sbin/httpd
   else

     echo "  Path to apache could not be determined. This is a custom environment" | tee -a $LOG
     echo "  Please contact the services group at support@atomicorp.com for a custom" | tee -a $LOG
     echo "  installation quote." | tee -a $LOG
     echo
     app_exit 1
   fi

	cpanel_ea3_install
	cpanel_common_install
	/var/asl/data/templates/template-cpanel-apache-hook | tee -a $LOG


elif [ -d /usr/local/cpanel ]; then
  	echo "cpanel Detected..." | tee -a $LOG
  	CPANEL=1
		apachectl -v | grep -i cpanel
		RETVAL=$?

	if [ -f /usr/local/cpanel/whostmgr/docroot/cgi/lsws/chkLSRunning.sh ]; then
		cpanel_litespeed_install
		cpanel_common_install

	elif [ "$RETVAL" -eq 0 ]; then

		EA_VERSION=$(/scripts/easyapache --version 2>/dev/null |grep "Easy Apache v3")

		if ! /scripts/easyapache --version 2>/dev/null |grep -q "Easy Apache v3"; then

    	 		HTTPD=/usr/sbin/httpd
					cpanel_ea4_install
					cpanel_common_install

		else

    			HTTPD=/usr/local/apache/bin/httpd
					cpanel_ea3_install
					cpanel_common_install
					cpanel_ea3_install_post
		fi


	else
	     echo "  Path to apache could not be determined. This is a custom environment" | tee -a $LOG
	     echo "  Please contact the services group at support@atomicorp.com for a custom" | tee -a $LOG
	     echo "  installation quote." | tee -a $LOG
	     echo
	     app_exit 1
	fi


	# bashrc
	$GET -q http://updates.atomicorp.com/installers/cpanel/bashrc | tee -a $LOG
	if [ ${PIPESTATUS[0]} -ge 1 ]; then
		app_exit 1
	fi

	$GET -q http://updates.atomicorp.com/installers/cpanel/profile-cpanel.sh | tee -a $LOG
	if [ ${PIPESTATUS[0]} -ge 1 ]; then
		app_exit 1
	fi

	# import cpanel functions to /etc/profile.d/cpanel.sh
	chattr -i /etc/bashrc
	install -m 0755 bashrc /etc/bashrc
	install -m 0755 profile-cpanel.sh /etc/profile.d/cpanel.sh

	# Fix 2: Correct /etc/init.d/mysqld script
	if [ ! -h /etc/init.d/mysqld -a -f  /etc/init.d/mysql ]; then
		ln -sf /etc/init.d/mysql /etc/init.d/mysqld
	fi


	# Issue #1900
	if [ "$DIST" == "el7" ]; then
		if [ ! -h /etc/init.d/mariadb -a -f  /etc/init.d/mysql ]; then
			ln -sf /etc/init.d/mysql /etc/init.d/mariadb
		fi
	fi


else
  echo "Standard" | tee -a $LOG

	if [ "$DIST" == "el7" ]; then
		# httpd 2.4 includes mod_sed natively
		yum -y install asl mod_security mod_evasive | tee -a $LOG
	else
		yum -y install asl  mod_security mod_evasive mod_sed | tee -a $LOG
	fi

    if [ ${PIPESTATUS[0]} -ge 1 ]; then
        echo
        echo "Error: Could not install ASL" |tee -a $LOG
        app_exit 1
    fi

fi

post_asl_install | tee -a $LOG