#!/usr/bin/perl

use MIME::Base64();

# Prompt for ATS details
print "ATS host: ";
$ATShost = <>;
chomp $ATShost;
$ATSport = 2645;

# Request authentication policy for end service
print "CASA enabled service host: ";
$CASAEnabledServer = <>;
chomp $CASAEnabledServer;
print "CASA enabled service name: ";
$CASAEnabledService = <>;
chomp $CASAEnabledService;

# Send auth-policy request
$getAuthPolicyReq = &getAuthPolicyRequest($CASAEnabledService, $CASAEnabledServer);
#print "$getAuthPolicyReq\n";
$ret = `curl -k -sS --data-binary \'$getAuthPolicyReq\' https://$ATShost:$ATSport/CasaAuthTokenSvc/Rpc?method=GetAuthPolicy`;
print $ret;
$ret =~ /<auth_policy>(.*)<\/auth_policy>/;
$authPolicyB64 = $1;
$authPolicy = MIME::Base64::decode($authPolicyB64);
print "\n\nPOLICY FOR $CASAEnabledService/$CASAEnabledServer:\n$authPolicy\n";
$authPolicy =~ /<realm>(.*)<\/realm>/;
$realm = $1;

if ($realm eq "") {
	print "Realm: ";
	$realm = <>;
	chomp $realm;
}

# Request session token
$authenticateReq = &getSessionTokenRequest($realm);
#print "$authenticateReq\n";
$ret = `curl -k -sS --data-binary \'$authenticateReq\' https://$ATShost:$ATSport/CasaAuthTokenSvc/Rpc?method=Authenticate`;
#print "$ret\n";
$ret =~ />([^>]*)<\/session_token>/;
$sessionTokenB64 = $1;
$sessionToken = MIME::Base64::decode($sessionTokenB64);
print "\n\nSESSION TOKEN CONTENTS:\n$sessionToken\n";

# Request auth token
$getAuthTokenReq = &getAuthTokenRequest($CASAEnabledService, $CASAEnabledServer, $sessionTokenB64);
#print "$getAuthTokenReq\n";
$ret = `curl -k -sS --data-binary \'$getAuthTokenReq\' https://$ATShost:$ATSport/CasaAuthTokenSvc/Rpc?method=GetAuthToken`;
open $tokfile, ">token.txt";
$ret =~ /(<auth_token>.*<\/auth_token>)/;
#print $tokfile "$1\n";
$ret =~ />([^>]*)<\/auth_token>/;
$authTokenB64 = $1;
$WSS_msg = MIME::Base64::decode($authTokenB64);
print $tokfile "$WSS_msg\n";
$WSS_msg =~ /<ident_token_data>(.*)<\/ident_token_data>/;
$authToken = MIME::Base64::decode($1);
print "\n\nAUTH TOKEN ID INFO:\n$authToken\n";

# Validate the auth token
$ret = `./validate_auth_token.exe \'$CASAEnabledService\' \'$authTokenB64\'`;
print "$ret\n";

# CASA request URLs:
# 1. https://<host>:<port>/CasaAuthTokenSvc/Rpc?method=GetAuthPolicy
# 2. https://<host>:<port>/CasaAuthTokenSvc/Rpc?method=Authenticate
# 3. https://<host>:<port>/CasaAuthTokenSvc/Rpc?method=GetAuthToken

sub getAuthPolicyRequest {
	my ($service, $host, $policyRequest);
	$service = $_[0];
	$host = $_[1];

#	$policyRequest = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
	$policyRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<get_auth_policy_req>
<service>$service</service>
<host>$host</host>
</get_auth_policy_req>";

	return $policyRequest;
}

sub getSessionTokenRequest {
	my ($realm, $mechanismID, $mechanismTokenData, $sessionTokeniReq);
	$realm = $_[0];
#	print "Realm: ";
#	$realm = <>;
#	chomp $realm;

	# PwdAuthenticate or Krb5Authenticate
	$mechanismID = "PwdAuthenticate";
	$mechanismTokenData = &getPasswordMechToken();

	$sessionTokenReq = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
<auth_req>
<realm>$realm</realm>
<mechanism>$mechanismID</mechanism>
<auth_mech_token>$mechanismTokenData</auth_mech_token>
</auth_req>";

	return $sessionTokenReq;
}

sub getPasswordMechToken {
	my ($username, $password, $mechData, $mechTokenData);
	print "User: ";
	$username = <>;
	chomp $username;
	print "Password: ";
	$password = <>;
	chomp $password;
	$mechData = "$username\r\n$password\r\n";
	$mechTokenData = MIME::Base64::encode("$mechData", '');
	return $mechTokenData;
}

sub getKerberosMechToken {
}

sub getAuthTokenRequest {
	my ($service, $host, $sessionTokenB64, $authTokenReq);
	$service = $_[0];
	$host = $_[1];
	$sessionTokenB64 = $_[2];

	$authTokenReq = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<get_auth_tok_req>
<service>$service</service>
<host>$host</host>
<session_token>$sessionTokenB64</session_token>
</get_auth_tok_req>";

	return $authTokenReq;
}