#!/bin/bash

set -e

### Default values

# Set the vpn server name
VPN_NAME="eesyvpn"
# Set the vpn name displayed to the users
VPN_CLIENT_NAME="eesyvpn"
# set the vpn port used
VPN_PORT="1190"
# Set strengh of the Diffie-Hellman parameters
DH_STRENGH="2048"

# Certification Authority
CAHOME=/etc/eesyvpn/$VPN_NAME
CRT_DIR=$CAHOME/certs
CRT_REVOKED_DIR=$CRT_DIR/revoked
KEY_DIR=$CAHOME/private
KEY_REVOKED_DIR=$KEY_DIR/revoked
CSR_DIR=$CAHOME/csr
CSR_REVOKED_DIR=$CSR_DIR/revoked
PEM_DIR=$CAHOME/pem
PEM_REVOKED_DIR=$PEM_DIR/revoked
CACRT=$CRT_DIR/ca.crt
CAKEY=$KEY_DIR/ca.key
CRL_DIR=$CAHOME/crl
CRLPEM=$CRL_DIR/crl.pem
NEW_CRT_DIR=$CAHOME/misc/ca.db.certs
TA_KEY_DIR=$CAHOME/private
TA_KEY=$TA_KEY_DIR/ta.key
CCD_DIR=$CAHOME/ccd
DHFILE=$KEY_DIR/dh${DH_STRENGH}.pem

# Log configuration
VPN_LOG_DIR="/var/log"
VPN_LOG_NAME="openvpn-$VPN_NAME"
VPN_LOG_FILE="$VPN_LOG_DIR/${VPN_LOG_NAME}.log"
VPN_LOG_STATUS_FILE="$VPN_LOG_DIR/${VPN_LOG_NAME}-status.log"

# OpenSSL
OSSL_CNF_DIR=$CAHOME/openssl
OSSL_CNF=$OSSL_CNF_DIR/openssl.conf
OSSL_INDEX=$OSSL_CNF_DIR/index
OSSL_SERIAL=$OSSL_CNF_DIR/serial

OSSL_VAR_C="FR"
OSSL_VAR_ST="Ile de France"
OSSL_VAR_L="Paris"
OSSL_VAR_O="Easter-eggs"
OSSL_VAR_OU="$OSSL_VAR_O"
OSSL_VAR_EMAIL="postmaster@easter-eggs.com"
OSSL_VAR_CAHOME="$CAHOME"
OSSL_VAR_CANAME="$VPN_NAME"
OSSL_VAR_CRL_DAYS=7300

[ ! -n "$OSSL_CERT_TYPE" ] && OSSL_CERT_TYPE="client, email"

OSSL_CERT_SUBJ_FORMAT="/C=$OSSL_VAR_C/ST=$OSSL_VAR_ST/L=$OSSL_VAR_L/O=$OSSL_VAR_O/OU=$OSSL_VAR_OU/CN=%%CN%%/emailAddress=$OSSL_VAR_EMAIL"

# OpenVPN
OVPN_CNF_DIR=$CAHOME/openvpn
OVPN_CNF_CLIENTS_NAME=$VPN_CLIENT_NAME
OVPN_CNF_CLIENTS_DIR=$OVPN_CNF_DIR/clients
OVPN_CNF_CLIENTS_ZIP_DIR=$OVPN_CNF_CLIENTS_DIR
OVPN_CNF_CLIENTS_TPL=$OVPN_CNF_DIR/client.ovpn.tpl
OVPN_SERVER_CNF=$OVPN_CNF_DIR/openvpn.conf
OVPN_SERVER_LINK=/etc/openvpn/server/${VPN_NAME}.conf
SERVICE=openvpn-server@${VPN_NAME}.service

PROGNAME=$(basename $0)


### Functions

function check_ca_structure() {
	# Check structure
	[ ! -d $CAHOME ] && echo "ERROR : Certification Authority directory not found ($CAHOME). Check your configuration" && exit 1
	[ ! -f $CACRT ] && echo "ERROR : Certification Authority certificate not found ($CACRT). Check your configuration" && exit 1
	[ ! -f $CAKEY ] && echo "ERROR : Certification Authority key not found ($CAKEY). Check your configuration" && exit 1
	return 0
}

function check_directories() {
	# Create structural directories if not exists
	for dir in $CAHOME $KEY_DIR $KEY_REVOKED_DIR $CRT_DIR $CRT_REVOKED_DIR $CSR_DIR $CSR_REVOKED_DIR $PEM_DIR $PEM_REVOKED_DIR $NEW_CRT_DIR $OVPN_CNF_DIR $OVPN_CNF_CLIENTS_DIR $OVPN_CNF_CLIENTS_ZIP_DIR $OSSL_CNF_DIR $CRL_DIR $TA_KEY_DIR $CCD_DIR
	do
		if [ ! -d $dir ]
		then
			echo -n "  - create $dir : "
			mkdir -p $dir
			chmod 755 $dir
			echo done.
		fi
	done

	# Fix structural directories rights
	chmod 750 $KEY_DIR $CSR_DIR $TA_KEY_DIR $OVPN_CNF_CLIENTS_DIR $PEM_DIR $OSSL_CNF_DIR
	return 0
}

function init_openssl_config() {
	echo -n "INFO : Initialize Certification Authority OpenSSL configuration ($OSSL_CNF) : "
	cp /usr/share/doc/eesyvpn/example/openssl.conf $OSSL_CNF
	sed -i "s/%%C%%/$OSSL_VAR_C/g" $OSSL_CNF
	sed -i "s/%%ST%%/$OSSL_VAR_ST/g" $OSSL_CNF
	sed -i "s/%%L%%/$OSSL_VAR_L/g" $OSSL_CNF
	sed -i "s/%%O%%/$OSSL_VAR_O/g" $OSSL_CNF
	sed -i "s/%%OU%%/$OSSL_VAR_OU/g" $OSSL_CNF
	sed -i "s/%%EMAIL%%/$OSSL_VAR_EMAIL/g" $OSSL_CNF
	sed -i "s@%%CAHOME%%@$OSSL_VAR_CAHOME@g" $OSSL_CNF
	sed -i "s@%%CANAME%%@$OSSL_VAR_CANAME@g" $OSSL_CNF
	sed -i "s@%%DEFAULT_CRL_DAYS%%@$OSSL_VAR_CRL_DAYS@g" $OSSL_CNF
	echo done.
	return 0
}

function set_dhparam_strengh() {
	echo "INFO : Generate OpenSSL dh$DH_STRENGH.pem file"
	openssl dhparam -out $DHFILE $DH_STRENGH
}

function check_openssl() {
	# OpenSSL
	[ ! -f $OSSL_CNF ] && init_openssl_config
	[ ! -f $OSSL_INDEX ] && echo "INFO : Initialize OpenSSL index file" && touch "$OSSL_INDEX"
	[ ! -f $OSSL_SERIAL ] && echo "INFO : Initialize OpenSSL serial file" && echo -n 01 > $OSSL_SERIAL
	[ ! -f $DHFILE ] && echo "ERROR: Diffie Hellman parameter is missing. Check your configuration" && exit 1
	return 0
}

function check_openvpn() {
	# OpenVPN
	[ ! -d $OVPN_CNF_DIR ] && echo "INFO : Create OpenVPN configuration directory" && mkdir $OVPN_CNF_DIR
	[ ! -f $OVPN_CNF_CLIENTS_TPL ] && echo "ERROR : OpenVPN configuration template file not found ($OVPN_CNF_CLIENTS_TPL). Check your configuration" && exit 1
	return 0
}

function to_humain_date() {
	echo $1|sed 's/\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)\([0-9][0-9]\)Z/20\1\/\2\/\3 \4:\5:\6/'
}

function create() {
	check_openssl && check_directories && check_openvpn

	if [ -f $CRT_DIR/$name.crt  -o -f $KEY_DIR/$name.key -o -f $PEM_DIR/$name.pem ]
	then
		echo "Name $name already used"
		exit 1
	fi

	echo "Generate key file : "
	openssl genrsa -out $KEY_DIR/$name.key 4096
	echo done.
	echo

	echo "Fix key file access right : "
	chmod 0600 $KEY_DIR/$name.key
	echo done.
	echo

	makecert


	if [ $server == 0 ]
	then
		if [ "$OS" == 'windows' ]
		then
			echo "We use Windows formated openvpn conf file by default"
			echo "If you want a linux version, use $PROGNAME create certificat_name -e linux"
		fi
		makeconf
		makezipconf
	fi
}

function makecert {
	check_openssl && check_directories && check_openvpn

	if [ ! -f $KEY_DIR/$name.key ]
	then
		echo "Key file of $name not found"
		exit 1
	fi

	echo -n "Generate csr file : "
	SUBJ=$( echo "$OSSL_CERT_SUBJ_FORMAT"|sed "s/%%CN%%/$name/g" )
	openssl req -new -key $KEY_DIR/$name.key -out $CSR_DIR/$name.csr -config $OSSL_CNF -subj "$SUBJ"
	echo done.
	echo

	#$0 sign $name "$3"
	sign

	if [ ! -f "$CRT_DIR/$name.crt" ]
	then
		echo "ERROR : Certificate file not found ($CRT_DIR/$name.crt)."
		exit 1
	fi

	echo -n "Generate pem file : "
	cat $KEY_DIR/$name.key >  $PEM_DIR/$name.pem
	cat $CRT_DIR/$name.crt >> $PEM_DIR/$name.pem
	echo done.
}

function sign {
	check_openssl && check_directories && check_openvpn

	if [ ! -f $CSR_DIR/$name.csr ]
	then
		echo "CSR not found: $CSR_DIR/$name.csr"
		exit 1
	fi
	if [ $server == 1 ]
	then
		EXT="-extensions server"
	else
		EXT=""
	fi
	openssl ca -config $OSSL_CNF -batch $EXT -out $CRT_DIR/$name.crt -infiles $CSR_DIR/$name.csr
	echo
	echo "CA verifying : "
	openssl verify -CAfile $CACRT $CRT_DIR/$name.crt
	echo
}

function recreate() {
	check_openssl && check_directories && check_openvpn

	if [ ! -f $CRT_DIR/$name.crt ]
	then
		echo "This name $name not currently exist"
		exit 1
	fi
	revoke
	create
}

function renew() {
	check_openssl && check_directories && check_openvpn

	if [ ! -f $CRT_DIR/$name.crt ]
	then
		echo "This name $name not currently exist"
		exit 1
	fi
	revoke --preserve-key
	makecert
	makeconf
	makezipconf
}

function revoke() {
	check_openssl && check_directories && check_openvpn

	if [ ! -f $CRT_DIR/$name.crt ]
	then
		echo "CRT not found: $CRT_DIR/$name.crt"
		exit 1
	fi
	echo "Revoke CRT : "
	openssl ca -config $OSSL_CNF -revoke $CRT_DIR/$name.crt
	echo done.
	echo
	echo -n "Move old certificate in revoked directory : "
	mv -f $CRT_DIR/$name.crt $CRT_REVOKED_DIR/
	mv -f $PEM_DIR/$name.pem $PEM_REVOKED_DIR/
	mv -f $CSR_DIR/$name.csr $CSR_REVOKED_DIR/
	[ "$1" != "--preserve-key" ] && mv -f $KEY_DIR/$name.key $KEY_REVOKED_DIR/
	echo done.

	update-crl
}

function update-crl() {
	check_openssl && check_directories && check_openvpn

	echo "Update CRL ($CRLPEM) : "
	openssl ca -gencrl -config $OSSL_CNF -out $CRLPEM
	echo done.

	echo "Verify crl checking is enabled in your conf: $OVPN_SERVER_CNF"
	if [ -f "$OVPN_SERVER_CNF" ]
	then
		sed -i "s/#crl-verify/crl-verify/g" $OVPN_SERVER_CNF
		echo done.
		echo "Restarting service.."
		/bin/systemctl restart $SERVICE
	fi
}

function makeconf() {
	check_openssl && check_directories && check_openvpn

	ovpn=$OVPN_CNF_CLIENTS_DIR/${OVPN_CNF_CLIENTS_NAME}.ovpn
	echo "Make OpenVPN client config file"
	if [ "$OS" = 'linux' ]; then
		cat $OVPN_CNF_CLIENTS_TPL > $ovpn
	else
		cat $OVPN_CNF_CLIENTS_TPL|unix2dos > $ovpn
	fi

	quoted_name=$(echo $name | sed 's/\([%@$]\+\)/\\\1/')
	if [ $( grep -c '%%CERT%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(%%CERT%%)($( echo ${quoted_name}.crt ))" $ovpn
	fi
	if [ $( grep -c '%%KEY%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(%%KEY%%)($( echo ${quoted_name}.key ))" $ovpn
	fi
	if [ $( grep -c '%%CACRT%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(%%CACRT%%)(ca.crt)" $ovpn
	fi
	if [ $( grep -c '%%TA_KEY%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(%%TA_KEY%%)(ta.key)" $ovpn
	fi

	if [ "$OS" = 'linux' ]; then
		mv $OVPN_CNF_CLIENTS_DIR/${OVPN_CNF_CLIENTS_NAME}.ovpn  $OVPN_CNF_CLIENTS_DIR/${OVPN_CNF_CLIENTS_NAME}.conf
		ovpn=$OVPN_CNF_CLIENTS_DIR/${OVPN_CNF_CLIENTS_NAME}.conf
		sed -i "/^# Required on Microsoft Windows 7/d" $ovpn
		sed -i "/^route-method exe/d" $ovpn
		sed -i "/^route-delay 2/d" $ovpn
	fi
	echo "OpenVPN client config file created in:"
	echo "  $ovpn"
	echo done.
}

function makezipconf() {
	check_openssl && check_directories && check_openvpn

	for conf in `find $OVPN_CNF_CLIENTS_DIR \( -iname ${OVPN_CNF_CLIENTS_NAME}.conf -o -iname ${OVPN_CNF_CLIENTS_NAME}.ovpn \)`
	do
		ovpn=$conf
	done
	[ ! -f $ovpn ] && makeconf

	ADD_IN_ZIP="$CRT_DIR/${name}.crt $KEY_DIR/${name}.key	$CACRT $TA_KEY"

	if [ -n "$ADD_IN_ZIP" ]
	then
		zip=$OVPN_CNF_CLIENTS_ZIP_DIR/${name}.zip
		echo "Make OpenVPN client zip config file : $zip"
		[ -f $zip ] && echo  -n "Remove old OpenVPN client config zip file : " && rm -f $zip && echo done.
		zip -r $zip -j $ADD_IN_ZIP $ovpn
		echo done.
	else
		echo "No additional file detected. Don't generate zip file, just use OpenVPN client config file : $ovpn"
	fi
}

function makeovpnconf() { 
	check_openssl && check_directories && check_openvpn

	ovpn=$OVPN_CNF_CLIENTS_DIR/${name}.ovpn
	echo "Make OpenVPN client config file"
	cat $OVPN_CNF_CLIENTS_TPL > $ovpn

	if [ $( grep -c 'cert %%CERT%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(cert %%CERT%%)($(echo '<cert>\n')$( cat $CRT_DIR/${name}.crt )$(echo '\n</cert>'))" $ovpn
	fi
	if [ $( grep -c 'key %%KEY%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(key %%KEY%%)($(echo '<key>\n')$( cat $KEY_DIR/${name}.key )$(echo '\n</key>'))" $ovpn
	fi
	if [ $( grep -c 'ca %%CACRT%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(ca %%CACRT%%)($(echo '<ca>\n')$( cat $CACRT )$(echo '\n</ca>'))" $ovpn
	fi

	if [ $( grep -c 'tls-auth %%TA_KEY%%' $ovpn ) -gt 0 ]
	then
		perl -pi -e "s(tls-auth %%TA_KEY%%)($(echo '<tls-auth>\n')$( cat $TA_KEY )$(echo '\n</tls-auth>'))" $ovpn
	fi

	if [ "$OS" = 'linux' ]; then
		mv $OVPN_CNF_CLIENTS_DIR/${name}.ovpn  $OVPN_CNF_CLIENTS_DIR/${name}.conf
		ovpn=$OVPN_CNF_CLIENTS_DIR/${name}.conf
		sed -i "/^# Required on Microsoft Windows 7/d" $ovpn
		sed -i "/^route-method exe/d" $ovpn
		sed -i "/^route-delay 2/d" $ovpn
	fi
	if [ "$OS" != 'linux' ]; then
		unix2dos $ovpn
	fi
	echo "OpenVPN client config file created in:"
	echo "  $ovpn"
	echo done.
}

function initialize() {
	echo "Initialize CA with servername $name :"

	if [ -e "$CAHOME" -o -e "$CAKEY" -o -e "$CACRT" ]
	then
		echo "ERROR : Installation already initialized."
		echo
		echo "  If you want to reset your installation, please remove manually"
		echo "  configuration directory :"
		echo "    $CAHOME"
		exit 1
	fi

	for dir in $CAHOME $OSSL_CNF_DIR $OVPN_CNF_DIR
	do
		if [ ! -d $dir ]
		then
			echo -n "  - create $dir : "
			mkdir -p $dir
			chmod 755 $dir
			echo done.
		fi
	done
	[ ! -f $OSSL_CNF ] && init_openssl_config

	echo "Build Easy RSA temporary directory : "
	EASYRSA_DIR=$( mktemp -d -u )
	make-cadir $EASYRSA_DIR
	[ ! -d "$EASYRSA_DIR" -o ! -e "$EASYRSA_DIR/easyrsa" ] && echo "ERROR : problem occured creating Easy RSA directory." && exit 1
	echo done.

	cd "$EASYRSA_DIR"

	# Run clean-all to auto-create keys dir
	./easyrsa clean-all

	export KEY_COUNTRY="$OSSL_VAR_C"
	export KEY_PROVINCE="$OSSL_VAR_ST"
	export KEY_CITY="$OSSL_VAR_L"
	export KEY_ORG="$OSSL_VAR_O"
	export KEY_EMAIL="$OSSL_VAR_EMAIL"
	#export KEY_CN="$name"
	export KEY_NAME="$name"
	export KEY_OU="$OSSL_VAR_OU"
	export EASYRSA_CA_EXPIRE=7210

	mkdir $KEY_DIR $CRT_DIR
	./easyrsa build-ca
	[ $? -ne 0 ] && echo "ERROR: Create CA failed" && exit 1

	echo "Copy generated files in CA directory :"
	echo -n "  - Key ($CAKEY) : "
	mv pki/private/ca.key $CAKEY
	echo done.

	echo -n "  - Certificate ($CACRT) : "
	mv pki/ca.crt $CACRT
	echo done.

	cd $CAHOME

	echo "Clean Easy RSA temporary directory :"
	cd $CAHOME
	rm -fr "$EASYRSA_DIR"
	echo done.

	if [ ! -f "$OVPN_CNF_CLIENTS_TPL" ]
	then
		echo "Create client template configuration : "
		cp /usr/share/doc/eesyvpn/example/client.ovpn.tpl $OVPN_CNF_CLIENTS_TPL
		sed -i "s/%%HOSTNAME%%/$name/g" $OVPN_CNF_CLIENTS_TPL
		sed -i "s/%%VPN_PORT%%/$VPN_PORT/g" $OVPN_CNF_CLIENTS_TPL
		echo done.
	fi

	echo "Clean previous generated TA key and build an new one : "
	[ -f $TA_KEY ] && rm -f $TA_KEY
	openvpn --genkey --secret $TA_KEY
	echo done

	[ ! -f $DHFILE ] && set_dhparam_strengh

	echo -n "Create VPN server key and certificate :"
	create
	echo done.
	SRVKEY=$KEY_DIR/${name}.key
	SRVCRT=$CRT_DIR/${name}.crt

	echo "Fixed configuration files access rights :"

	echo -n "  - Key files : "
	chmod 0600 $CAKEY $TA_KEY $SRVKEY
	echo done.

	echo -n "  - Certificates files : "
	chmod 0644 $CACRT $SRVCRT
	echo done.

	if [ ! -f "$OVPN_SERVER_CNF" ]
	then
		echo -n "Create server configuration : "
		cp /usr/share/doc/eesyvpn/example/openvpn.conf $OVPN_SERVER_CNF
		sed -i "s|%%HOSTNAME%%|$name|g" $OVPN_SERVER_CNF
		sed -i "s|%%VPN_NAME%%|$VPN_NAME|g" $OVPN_SERVER_CNF
		sed -i "s|%%VPN_PORT%%|$VPN_PORT|g" $OVPN_SERVER_CNF
		sed -i "s|%%SRVKEY%%|$SRVKEY|g" $OVPN_SERVER_CNF
		sed -i "s|%%SRVCRT%%|$SRVCRT|g" $OVPN_SERVER_CNF
		sed -i "s|%%CACRT%%|$CACRT|g" $OVPN_SERVER_CNF
		sed -i "s|%%DHFILE%%|$DHFILE|g" $OVPN_SERVER_CNF
		sed -i "s|%%TA_KEY%%|$TA_KEY|g" $OVPN_SERVER_CNF
		sed -i "s|%%CRLPEM%%|$CRLPEM|g" $OVPN_SERVER_CNF
		sed -i "s|%%CCD_DIR%%|$CCD_DIR|g" $OVPN_SERVER_CNF
		sed -i "s|%%VPN_LOG_FILE%%|$VPN_LOG_FILE|g" $OVPN_SERVER_CNF
		sed -i "s|%%VPN_LOG_STATUS_FILE%%|$VPN_LOG_STATUS_FILE|g" $OVPN_SERVER_CNF
		ln -s $OVPN_SERVER_CNF $OVPN_SERVER_LINK
		echo done.

		if [ -d /run/systemd/system ]
		then

			echo "Enable service on boot :"
			/bin/systemctl enable $SERVICE
			echo done.

			echo "Start service : "
			/bin/systemctl start $SERVICE
			/bin/systemctl status $SERVICE
		else
			# OpenVPN is enabled by default on init V debian installation
			/etc/init.d/openvpn start $VPN_NAME
		fi
	fi
}

function list() {
	check_openssl && check_directories && check_openvpn

	if [ "$2" == "--csv" ]
	then
		CSV=1
	else
		CSV=0
		echo "ID | State | Type   | Expiration date     | Revocation date     | Name"
		echo "---+-------+--------+---------------------+---------------------+------------------------------"
	fi
	IFS="
"
	for line in $( cat $OSSL_INDEX )
	do
		state=$( echo "$line"| cut -f1 )
		expdate=$( echo "$line"|cut -f2 )
		expdate=$( to_humain_date $expdate )
		revdate=$( echo "$line"|cut -f3 )
		revdate=$( to_humain_date $revdate )
		id=$( echo "$line"|cut -f4 )
		fields=$( echo "$line"|cut -f6 )
		cn=$( echo "$fields"|sed 's/^.*CN=\([^\/]*\).*$/\1/' )
		if [ $( openssl x509 -noout -text -in "$NEW_CRT_DIR/$id.pem"|grep -c "SSL Server" ) -eq 1 ]
		then
			typ="server"
		else
			typ="client"
		fi

		if [ $CSV -eq 1 ]
		then
			echo "'$id';'$cn';'$state';'$typ';'$expdate';'$revdate'"
			continue
		fi
		if [ "$revdate" == "" ]
		then
			revdate="                   "
		fi
		echo "$id | $state     | $typ | $expdate | $revdate | $cn"
	done
}

function view() {
	check_openssl && check_directories && check_openvpn

	if [ -f "$CRT_DIR/$name.crt" ]
	then
		crt="$CRT_DIR/$name.crt"
	elif [ -f "$NEW_CRT_DIR/$name.pem" ]
	then
		crt="$NEW_CRT_DIR/$name.pem"
	else
		echo "Invalid name"
		exit 1
	fi
	openssl x509 -noout -text -in "$crt"
}

function namebyid() {
	check_openssl && check_directories && check_openvpn

	if [ -f "$NEW_CRT_DIR/$name.pem" ]
	then
		openssl x509 -noout -text -in "$NEW_CRT_DIR/$name.pem"|grep Subject:|sed 's/^.*CN=\([^ ,]*\).*$/\1/'
	else
		echo "Invalid ID"
		exit 1
	fi
}

function usage() {
	echo
	cat <<-EOF
	Usage:
	  $PROGNAME {create|recreate|view|renew|revoke|makeconf|makezipconf|makeovpnconf|makecert|namebyid} certificate_name [options]
	  $PROGNAME {list|update-crl} [options]
	  $PROGNAME initialize [you.server.fqdn] [-f config-file]

	To create a new VPN server, first initialize it :
	  $PROGNAME initialize [you.server.fqdn] [-f config-file]
	You can then add user authenticated by certificates :
	  $PROGNAME create certificate_name [-e OS] [-f config-file]

	Main Commands: 

	  create certificate_name [-e OS] - Create user certificate. (default with dos format. Specify an extra arg 'linux' to use linux format & conffile)
	  list [-f config-file] - List all certificates
	  initialize - To initialize your CA, run $PROGNAME initialize [your.server.fqdn] [-f config-file]

	Options:
        
	-e OS (windows|linux) - Specifies the client OS. The defaut is windows
	-f config-file - Specifies the VPN configuration file. The default is /etc/eesyvpn/eesyvpn.conf
	-h Displays this help text 
	EOF
}

### Parsing and checking parameters

# checking actions
action=$1
action=${action%% *}
if [ ! -n "$action" ]
then
	usage
	exit 0
fi

actions="create recreate view renew revoke makeconf makezipconf makeovpnconf makecert namebyid list update-crl initialize"
[[ ! $actions =~ (^|[[:space:]])$action($|[[:space:]]) ]] && echo "ERROR : Unknown command"  && usage && exit 1

shift

if [ "$action" != "update-crl" -a "$action" != "list" ]
then
	if [ ! -n "$1" ]
	then 
		echo certificate_name not defined
		usage
		exit 1
	else	
		name=$1
		shift
	fi
fi

if [ "$action" == "initialize" ]
then
	server=1
else
	server=0
fi

# Default option values
OS="windows"
configfile="/etc/eesyvpn/eesyvpn.conf"

# Parsing and checking options
optstring=":e:f:h:"
while getopts "$optstring" o; do
	case "$o" in
		e) 
			OS="$OPTARG"
			[ "$OS" != "windows" -a "$OS" != "linux" ] && usage && exit 1
		;;
		f)
			configfile="$OPTARG"
			[ ! -f "$configfile" ] && usage && exit 1
		;;
		h)
			usage
			exit 0
		;;
		:)
      			echo "${PROGNAME}: Must supply an argument to -${OPTARG}." >&2
			usage
      			exit 1
      		;;
    		?)
      			echo "Invalid option: -${OPTARG}."
			usage
      			exit 1
		;;
	esac
done

[ -f $configfile ] && source $configfile

if [ "$action" != "initialize" -a ! -d $CAHOME ]
then
	echo "ERROR: You must first initialize a VPN with the initialize command" 
	usage 
	exit 1
fi

### Main
$action

exit 0
