###########################################################################
##
## RC4 for irssi 
## Like IDEA plugin but uses RC4 :-)
##
## RootBear / OH3NWQ Dec 2010
##
## See the color formats near the end of the script
##
## Based on MORSE for irssi by
## Goblet / OH2MMY  Nov 2001
##
## Might not support WTF8, but who the *uck cares.
##
## This script is published under EVVKTVH: http://evvk.com/evvktvh.html
## Insert your bug reports and/or complaints into your ass.
##
## Uses MIME::Base64
##
##
##
## Uses Crypt::RC4
##
## Copyright (C) 2006 DelTel, Inc.
##
## This library is free software; you can redistribute it and/or modify
## it under the same terms as Perl itself, either Perl version 5.8.5 or,
## at your option, any later version of Perl 5 you may have available.
##
###########################################################################

use Irssi;
use Irssi::Irc;
use Irssi::UI;
use Crypt::RC4;
use MIME::Base64;

use strict;

## enter here key that is used for RC4, any number of characters
my $passphrase = "password";

my $version = "1.2";
my $blocksize = 8;

my $dec_status;
my $original;


# utf8-conversion between utf8 and latin9 
# 1 to use, 0 not to use
my $utf8_to_l9 = "0";
my $l9_to_utf8 = "1";

if ($utf8_to_l9 and $l9_to_utf8) {  
  die "Unsufficient user IQ error.\n"; 
}


sub encode_RC4 {
  my ($str) = @_;
  my $encrypted = RC4($passphrase, $str);
  return $encrypted;
}


sub decode_RC4 {
  my ($str) = @_;

  my $decrypted = RC4( $passphrase, $str);
  return $decrypted;
}


sub decode_wtf8 {
  my ($str) = @_;
    if ($l9_to_utf8) {
  #        $str =~ s/<A4>/\xC2\xA4/g;
          $str =~ s/\xE5/\xC3\xA5/g;
          $str =~ s/\xE4/\xC3\xA4/g;
          $str =~ s/\xF6/\xC3\xB6/g;
          $str =~ s/\xFC/\xC3\xBC/g;
          $str =~ s/\xC5/\xC3\x85/g;
          $str =~ s/\xC4/\xC3\x84/g;
          $str =~ s/\xD6/\xC3\x96/g;
          $str =~ s/\xDC/\xC3\x9C/g;
          $str =~ s/\xB5/\xC2\xB5/g;
          $str =~ s/\xA9/\xC2\xA9/g;
    } 
    if ($utf8_to_l9) {
          $str =~ s/\xC3\xA5/\xE5/g;
          $str =~ s/\xC3\xA4/\xE4/g;
          $str =~ s/\xC3\xB6/\xF6/g;
          $str =~ s/\xC3\x85/\xC5/g;
          $str =~ s/\xC3\x84/\xC4/g;
          $str =~ s/\xC3\x96/\xD6/g;
          $str =~ s/\xE2\x82\xAC/\xA4/g;
          $str =~ s/\xC2\xB5/\xB5/g;
          $str =~ s/\xC2\xA9/\xA9/g;
    } 
  return $str;
}


sub cmd_RC4_say {
  my ($data,$server,$witem) = @_;
  my $window = Irssi::active_win();
  my $encoded;

  if (!$server || !$server->{connected}) {
      Irssi::print("Not connected to server");
      return;
  }
  if ($data && $witem->{type} eq "CHANNEL") {

      # RC4
      $encoded = encode_RC4($data);

      # b64
      $encoded = encode_b64($encoded);

      $witem->command("^MSG ".$witem->{name}.
                     " |*E*|RC4|$version|$encoded|");
  } else {
      Irssi::print("No active channel in window");
  }
  $window->printformat(MSGLEVEL_MSGS,'RC4_own',$data);
}


sub encode_b64 {
  my ($inp) = @_;
  my $str = encode_base64($inp);
  return $str;
}


sub decode_b64 {
  my ($inp) = @_;
  if ((length ($inp)) %4 != 0){
      return "RC4 B64 ERROR: invalid length ". length($inp)." bytes";
  }
  my $str = decode_base64($inp);
  return $str;
}


sub check_RC4 {
  my ($srv, $data, $nick, $addr) = @_;
  my ($dest, $text) = split(/ :/, $data, 2);
  my $server = Irssi::active_server();
  my ($dummy, $tag, $proto, $ver, $txt) = split(/\|/,$text);

  if ($tag eq "*E*" && $proto eq "RC4") {
    $original = $text;
    $dec_status = 0;

    # b64
    $txt = decode_b64($txt);

    # RC4
    $txt = decode_RC4($txt);

    # wtf8
    $txt = decode_wtf8($txt);

    $server->printformat($dest,MSGLEVEL_PUBLIC,'RC4_pub',$nick,$txt);

    Irssi::signal_stop();
  }
}


Irssi::theme_register([
  'RC4_own', '%yRC4 %n%w>%g $0-',
  'RC4_pub', '%yRC4 %n%c<$0>%n $1-',
  'RC4_error', '%rRC4 ERROR %n%c<$0>%n $1-'
]);


Irssi::signal_add("event privmsg", "check_RC4");
Irssi::command_bind("rc4", "cmd_RC4_say");
Irssi::print("RC4 $version loaded :-P");

