#!/bin/bash
# Linux automated OpenvPN installer for VPNSecure.me
# Attempt to get username/password information from a user for setup
# Can be autodownloaded and run by running
# wget https://www.vpnsecure.me/files/linux-openvpn-setup && bash linux-openvpn-setup
domain="www.vpnsecure.me"
sl="https://$domain/545s136s4dw8/serverListSabiEnc.php"
k='sabaai'; m='6c537f417d42af419241ad49';
home="/home/`whoami`"
storagelocation="/tmp/vpnsecure"
storagelocationtmp="$storagelocation/tmp"
openvpnlocation="/etc/openvpn"
programlocation="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
regourl="https://$domain/members"
apiurl=""
authenticated=0
username=""
password=""

function generate-networkmanager {
# Generate network manager configuration files
username=$1
server=$2
port=$3
proto=$4
uuid=`uuidgen`
description=$5

echo "[connection]"
echo "id=$description"
echo "uuid=$uuid"
echo "type=vpn"
echo
echo "[vpn]"
echo "service-type=org.freedesktop.NetworkManager.openvpn"
echo "connection-type=tls"
echo "remote=$server"
echo "cipher=DES-CBC"
echo "comp-lzo=yes"
echo "cert-pass-flags=1"
echo "port=$port"
echo "cert=$openvpnlocation/$username.crt"
echo "ca=$openvpnlocation/ca.crt"
echo "key=$openvpnlocation/$username.key"
if [[ $proto == tcp ]]; then
echo "proto-tcp=yes"
fi
echo
echo "[ipv4]"
echo "method=auto"
}

function generate-ovpn {
# Generate .ovpn files for OpenVPN
username=$1
server=$2
port=$3
proto=$4
echo "client"
echo "proto $proto"
echo "dev tun"
echo "ca ca.crt"
echo "cert $username.crt"
echo "key $username.key"
echo "remote $server $port"
echo "cipher DES-CBC"
echo "verb 2"
echo "mute 20"
echo "keepalive 10 20"
echo "comp-lzo"
echo "persist-key"
echo "persist-tun"
echo "float"
echo "resolv-retry infinite"
echo "nobind"
echo "auth-nocache"
echo "ns-cert-type server"
}

function authenticate {
if [[ $uitype == "gnome" ]]; then
# Get username/password via zenity dialogs
username=$(zenity --entry --text "What's your username?" --entry-text "$username" --title "VPNSecure Username");
password=$(zenity --entry --text "Hi $username ! What's your password?" --entry-text "$password" --title "VPNSecure Password");
else
# Get username/password via bash prompts
echo "What's your username ?"
read username
echo "Hi $username ! What's your password ?"
read password
fi

if [[ $username == "" ]]; then
echo "No username entered - Aborting"
exit
fi
if [[ $password == "" ]]; then
echo "No password entered - Aborting"
exit
fi

}

function getkeys {
# Get users keyfiles
$sudo curl --data-urlencode -s -o $storagelocationtmp/$username-key.zip "https://$domain/545s136s4dw8/oldkeymac.php?key=be8066bc33a5185125265c622d91c1b2&938c8374=$username&938x2387=$password"
}

function checkkeys {
# Check keys downloaded correctly
fileverify=`$sudo file $storagelocationtmp/$username-key.zip`
echo $fileverify|grep "$username-key.zip: data"
if [[ $? == 0 ]]; then
echo "Authentication passed"
authenticated=1
else
echo "Authentication failed! Asking again"
authenticated=0
fi
}

function checkdistro {
## Lets figure out what distribution the user is running
detectedDistro="Unknown"
regExpLsbInfo="Description:[[:space:]]*([^ ]*)"
regExpLsbFile="/etc/(.*)[-_]"

if [ `which lsb_release 2>/dev/null` ]; then       # lsb_release available
   lsbInfo=`lsb_release -d`
   if [[ $lsbInfo =~ $regExpLsbInfo ]]; then
      detectedDistro=${BASH_REMATCH[1]}
   else
      echo "??? Should not occur: Can't find distro name in lsb_release output ???"
      exit 1
   fi

else                                               # lsb_release not available
   etcFiles=`ls /etc/*[-_]{release,version} 2>/dev/null`
   for file in $etcFiles; do
      if [[ $file =~ $regExpLsbFile ]]; then
         detectedDistro=${BASH_REMATCH[1]}
         break
      else
         echo "??? Should not occur: Can't find any etcFiles ???"
         exit 1
      fi
   done
fi

detectedDistro=`echo $detectedDistro | tr "[:upper:]" "[:lower:]"`

case $detectedDistro in
	suse) 	detectedDistro="opensuse" ;;
        linux)	detectedDistro="linuxmint" ;;
esac
echo "Detected distro: $detectedDistro"

# Check if GNOME desktop UI is running
ps -C gnome-session > /dev/null
if [[ $? == 0 ]]; then
echo "Gnome desktop environment is running"
uitype="gnome"
sudo="sudo"
else
ps|grep -v "grep"|grep kdeinit
if [[ $? == 0 ]]; then
echo "KDE desktop environment is running"
uitype="kde"
sudo="sudo"
else
echo "Neither Gnome or KDE were detected - defaulting to text only bash install"
uitype="bash"
sudo="sudo"
fi
fi

# Check if NetworkManager is running
ps -C NetworkManager > /dev/null
if [[ $? == 0 ]]; then
echo "NetworkManager is running"
networkmanager="running"
else
echo "NetworkManager is not running"
networkmanager="stopped"
fi

}

function checkdependancies {
## Make sure all the dependancies are installed
# Need to check for: zenity, openvpn, network-manager-openvpn, firefox, curl, unzip
echo "Checking and installing dependancies"
case $detectedDistro in

ubuntu)	if [[ $uitype == "gnome" ]]; then
	# Graphical Installer dependencies: zenity
	if [[ $networkmanager="running" ]]; then
		$sudo apt-get --force-yes install openvpn zenity network-manager-openvpn curl unzip
	else
		$sudo apt-get --force-yes install openvpn zenity curl unzip
	fi
	else
	# Text Installer dependencies: none
		$sudo apt-get install --force-yes openvpn curl unzip
	fi
	;;

fedora) if [[ $uitype == "gnome" ]]; then
	if [[ $networkmanager == "running" ]]; then
		$sudo yum -y install openvpn zenity NetworkManager-openvpn curl unzip
	else
		$sudo yum -y install openvpn zenity curl unzip
	fi
	else
		$sudo yum -y install openvpn curl unzip
	fi
	;;

opensuse) if [[ $uitype == "gnome" ]]; then
	if [[ $networkmanager == "running" ]]; then
		# Gnome + Networkmanager dependancies
		$sudo zypper -n install zenity openvpn curl unzip networkmanager-openvpn
	else
		# Gnome without Networkmanager
		$sudo zypper -n install zenity openvpn curl unzip
	fi
	fi
	if [[ $uitype == "kde" ]]; then
	# KDE users only get standard openvpn installation at this point	
	#if [[ $networkmanager == "running" ]]; then
		#KDE + Networkmanager
	#	sudo zypper -n install zenity openvpn curl unzip networkmanager-openvpn networkmanager-openvpn-kde4
	#else
		#KDE without Networkmanager
		$sudo zypper -n install zenity openvpn curl unzip
	#fi
	fi
	;;

mepis) if [[ $uitype == "gnome" ]]; then
      	 	if [[ $networkmanager == "running" ]]; then
                	# Gnome + Networkmanager dependancies
	                $sudo apt-get --force-yes install zenity openvpn curl unzip networkmanager-openvpn uuid-runtime
        	else
        	    	# Gnome without Networkmanager
                	$sudo apt-get --force-yes install zenity openvpn curl unzip uuid-runtime
        	fi
	fi
	if [[ $uitype == "kde" ]]; then
        	# KDE users only get standard openvpn installation at this point
	        if [[ $networkmanager == "running" ]]; then
        	        #KDE + Networkmanager
        		$sudo apt-get --force-yes install zenity openvpn curl unzip networkmanager-openvpn networkmanager-openvpn-kde uuid-runtime
	        else
        	     	#KDE without Networkmanager
                	$sudo apt-get --force-yes install zenity openvpn curl unzip uuid-runtime
	        fi
        fi
	if [[ $uitype == "bash" ]]; then 
		# No gnome or kde detected
		$sudo apt-get --force-yes install openvpn curl unzip uuid-runtime
	fi
        ;;

*)	echo "Unsupported linux distribution detected!"
	echo "Installer cannot automatically detect and install the following required components:"
	echo "openvpn, zenity, network-manager-openvpn, curl, unzip, file"
	echo "Press Control-C to cancel install here, or any other key to continue installation anyway"
	read -e PAUSE
	;;
esac
}


### Main program flow starts here ###
if [[ $# == 0 ]]; then
checkdistro
checkdependancies
else
uitype="bash"
networkmanager="stopped"
fi
$sudo mkdir -p $storagelocationtmp
$sudo chown -R `whoami` $storagelocationtmp
cd $storagelocationtmp
if [[ $uitype == "gnome" ]]; then
zenity --question --text="Have you previously registered and purchased a VPN account ?"
if [[ $? == 0 ]]; then
echo "Answered Yes"
else
echo "Answered No"
echo "Launching browser to registration page"
zenity --info --text "Please register and purchase an account and then close browser to continue setup"
if which xdg-open > /dev/null
then
  xdg-open $regourl
elif which gnome-open > /dev/null
then
  gnome-open $regourl
fi
fi
else
echo "Be sure to register and purchase an account at $regourl before continuing!"
fi
while [ $authenticated == 0 ]; do
authenticate
getkeys
checkkeys
done

echo "Unpacking keyfiles and moving to final destination"
unzip -o $storagelocationtmp/$username-key.zip > /dev/null
$sudo mv -f $storagelocationtmp/$username.* $openvpnlocation/
$sudo mv -f $storagelocationtmp/ca.crt $openvpnlocation/ca.crt
$sudo mv -f $storagelocationtmp/dh2048.pem $openvpnlocation/dh2048.pem
$sudo rm -rf $storagelocationtmp/*

# Get server list for user using API
rand="$(head -c32 /dev/urandom | md5sum | tr -d ' -')";
salt="${rand:0:8}";
salt64="$(echo -n $salt | openssl enc -e -a -A)";
K="$(echo -n $salt$k | md5sum | tr -d ' -')";
I="$(echo -n $salt$m | md5sum | tr -d ' -')";
con="$(echo "$username,$password"|openssl aes-128-cbc -e -a -A -K $K -iv $I | tr '+' '.')";
serverlist=`curl --data-urlencode -s $sl'?plz='$salt64$con | openssl aes-128-cbc -d -a -A -nosalt -K $K -iv $I|sed 's|<br/>|\n|g'`
serverlistcount=`echo "$serverlist"|wc -l`
echo "Creating configuration files for $serverlistcount servers"
count=1
while [ $count -lt `expr $serverlistcount + 1` ]
do
serverline=`echo "$serverlist"|head -n$count|tail -1`
serveraddress=`echo "$serverline"|cut -d '|' -f2`
serverport=`echo "$serverline"|cut -d '|' -f3`
serverproto=`echo "$serverline"|cut -d '|' -f4`
serverlabel=`echo "$serverline"|cut -d '|' -f1`
filename="VPN-`echo "$serverlabel"|sed 's/\ //g'`"
if [[ $networkmanager == "running" ]]; then
generate-networkmanager $username $serveraddress $serverport $serverproto "$serverlabel"> $storagelocationtmp/$filename
fi
filename="$username-`echo "$serverlabel"|sed 's/\ //g'`.ovpn"
generate-ovpn $username $serveraddress $serverport $serverproto> $storagelocationtmp/$filename

echo "$storagelocationtmp/$filename generated!"
count=`expr $count + 1`
done

# Need to chmod configs to 600, copy to /etc/NetworkManager/system-connections, service NetworkManager restart, copy ca.crt username.crt username.key to /etc/openvpn
if [[ $networkmanager == "running" ]]; then
chmod 600 $storagelocationtmp/VPN*
$sudo cp $storagelocationtmp/VPN* /etc/NetworkManager/system-connections
$sudo gconftool-2 -R /etc/NetworkManager/system-connections
echo "Moved all network connection profiles into Network Manager folder and refreshed options"
fi
$sudo mv -f $storagelocationtmp/*.ovpn $openvpnlocation/
echo "OpenVPN configuration files moved to $openvpnlocation"
# Check if SELinux is enabled
sestatus|grep -q "enabled"
if [[ $? == 0 ]]; then
echo "SELinux is enabled"
selinuxstatus="enabled"
$sudo chcon -t cert_t $openvpnlocation/*
echo "Modified SELinux policy - allowing reading of certificates from $openvpnlocation"
else
echo "SELinux is disabled"
selinuxstatus="disabled"
fi
echo "Disabling OpenVPN service from loading on boot"
chkconfig openvpn off
echo "Cleaning up.."
$sudo rm -rf $storagelocationtmp
echo "Installed!"
