#!/usr/bin/perl

use File::Basename;
use MIME::Base64 qw( decode_base64 );

use lib dirname (__FILE__);

use NVPNConfig;
use NVPNLog;
use NVPNHTTP;
use NVPNIptd;

use constant {
	NVPN_VALIDATE_PARAM_USERNAME => "usernamex",
	NVPN_VALIDATE_PARAM_PASSWORD => "passwordx",
	NVPN_VALIDATE_PARAM_NAS => "nas",
	NVPN_VALIDATE_PARAM_IP => "local_1x",
	NVPN_PASS_CODE => "s",

	NVPN_CONNECT_PARAM_USERNAME => "username",
	NVPN_CONNECT_PARAM_REMOTE_IP => "ifconfig_pool_remote_ip",
	NVPN_CONNECT_PARAM_LOCAL_IP => "local_1",
	NVPN_CONNECT_PARAM_NAS => "nas",

	NVPN_DISCONNECT_PARAM_USERNAME => "username",
	NVPN_DISCONNECT_PARAM_IP => "externalip"
};

sub nvpn_get_password
{
        my ($username) = @_;

        my $http_url = nvpn_get_api_url("verify/chap.php");

        my %http_params = (
                &NVPN_VALIDATE_PARAM_USERNAME => $username,
                &NVPN_PASS_CODE => $NVPN_PASS_CODE
        );

        if ($username ne "")
        {
                my $result = nvpn_http_post($http_url, \%http_params);
                return nvpn_decode_password($username, $result);
        }
        else {
                nvpn_log(LOG_WARN, "chap validate: Data missing -> un: $username");
                return FAILURE;
        }
}

sub nvpn_decode_password
{
	my ($username, $encoded) = @_;

	my $magic = 0, $decoded = "";
	my @ints = unpack("I*", decode_base64($encoded));

	for ($i = 0 ; $i < length($username) ; $i++) {
		$magic += ord(substr($username, $i, 1));
	}

	for ($i = 0 ; $i < @ints ; $i++) {
        	$decoded .= chr(int($ints[$i]/($magic+$i)));
	}	

	return $decoded;
}

sub nvpn_validate_chap_user
{
        my ($username, $local_1, $nas) = @_;

        my $http_url = nvpn_get_api_url("verify/validate-chap.php");
        my %http_params = (
                &NVPN_VALIDATE_PARAM_USERNAME => $username,
                &NVPN_VALIDATE_PARAM_IP => $local_1,
		&NVPN_VALIDATE_PARAM_NAS => $nas
        );

        if ($username ne "")
        {
                my $result = nvpn_http_get($http_url, \%http_params);
                nvpn_log(LOG_WARN, "validate-chap: Data requested for user $username with status: $result");

                if ($result eq "pass") {
                        return SUCCESS;
                } else {
                        return FAILURE;
                }
        }
        else {
                nvpn_log(LOG_WARN, "validate-chap: Data missing -> un: $username, ip: $local_1");
                return FAILURE;
        }
}

sub nvpn_validate_user
{
	my ($username, $password, $local_1, $nas) = @_;

	my $http_url = nvpn_get_api_url("verify/validate.php");
	my %http_params = (
		&NVPN_VALIDATE_PARAM_USERNAME => $username,
		&NVPN_VALIDATE_PARAM_PASSWORD => $password,
		&NVPN_VALIDATE_PARAM_IP => $local_1,
		&NVPN_VALIDATE_PARAM_NAS => $nas
	);

	if ($password ne "" && $username ne "")
	{
		my $result = nvpn_http_get($http_url, \%http_params);
		nvpn_log(LOG_WARN, "validate: Data requested for user $username with status: $result");

		if ($result eq "pass") {
			return SUCCESS;
		} else {
			return FAILURE;
		}
	}
	else {
		nvpn_log(LOG_WARN, "validate: Data missing -> un: $username, pa: $password, ip: $local_1");
		return FAILURE;
	}
}

sub nvpn_handle_connect
{
	my ($username, $internalip, $externalip, $nas) = @_;

	if ($username ne "" && $internalip ne "" && $externalip ne "")
	{
		my $url = nvpn_get_api_url("verify/clientconnected.php?data=connect");
		my %params = (
			&NVPN_CONNECT_PARAM_USERNAME => $username,
			&NVPN_CONNECT_PARAM_REMOTE_IP => $internalip,
			&NVPN_CONNECT_PARAM_LOCAL_IP => $externalip,
			&NVPN_CONNECT_PARAM_NAS => $nas
		);
		my $content = nvpn_http_post($url, \%params);

        	my $retcode = 1;
		$retcode = 0 if grep /success/i, $content;

		if ($retcode == 0) {
			nvpn_log(LOG_WARN, "connect: Data sent for user $username with status: $retcode ($content)");
			return SUCCESS;
		} else {
			nvpn_log(LOG_WARN, "connect: Data transfer for user $username failed. Retcode=$retcode. ($content)");
			return FAILURE;
		}
	}

	nvpn_log(LOG_WARN, "connect: Data missing -> un: $username, iip: $internalip, eip: $externalip");
	return FAILURE;
}

sub nvpn_handle_disconnect
{
	my ($username, $internalip, $externalip, $nas) = @_;

	if ($username ne "" && $internalip ne "" && $externalip ne "")
	{
		my $url = nvpn_get_api_url("verify/clientdisconnect.php?data=disconnect");
		my %params = (
			&NVPN_DISCONNECT_PARAM_USERNAME => $username,
			&NVPN_DISCONNECT_PARAM_IP => $externalip,
			&NVPN_CONNECT_PARAM_NAS => $nas
		);
		my $content = nvpn_http_post($url, \%params);
		nvpn_log(LOG_WARN, "disconnect: Data sent for user $username with status: $content");

		nvpn_iptd_unregister($internalip);
		return SUCCESS;
	} else {
		nvpn_log(LOG_WARN, "disconnect: Data missing -> un: $username, iip: $internalip, eip: $externalip");
		return FAILURE;
	}
}

1;
