use Irssi;
use Digest::MD5 qw(md5_hex);
use strict;
use vars qw($VERSION %IRSSI);

$VERSION = '1.02';
%IRSSI = (
    authors 	=> 'Eric Jansen',
    contact 	=> 'chaos@sorcery.net',
    name 	=> 'identify-md5',
    description => 'MD5 NickServ identification script for SorceryNet',
    license 	=> 'GPL',
    changed 	=> 'Mon Feb 10 16:36:44 CET 2003'
);

################################################################################
#
#  MD5 NickServ identification script for SorceryNet (irc.sorcery.net)
#
#  The script will do two things:
#  - It adds the command /identify-md5 to Irssi, which can be used to identify
#    to your current nickname using the password provided below
#  - It will automatically issue this command whenever NickServ notices you 
#    that you need to identify (e.g. after a services outage)
#
#  For more information on SorceryNets MD5 identification see:
#  http://www.sorcery.net/help/howto/MD5_identify
#
#  Put your nicknames and MD5-hashed passwords here:
#

my %nicknames = (
    lc('nick1')		=> md5_hex('password1'), 		# Plain text password 'password1'
    lc('nick2')		=> '6cb75f652a9b52798eb6cf2201057c73',	# MD5-hash of password 'password2'
    lc('nick3')		=> md5_hex('password3')
);

#
#  Please note: This file should NOT be world-readable. Although it's (quite) 
#               impossible to get the original passwords from the hashes, a
#               malicious person can identify using the hash and then change
#               your password without knowing the old password.
#
################################################################################

sub cmd_identify
{
    my ($data, $server, $witem) = @_;

    # Are we connected?
    if(!$server || !$server->{'connected'})
    {
	Irssi::print("Not connected to a server.");
	return;
    }

    # Did the user define a password for his/her current nick?
    my $nickname = lc $server->{'nick'};
    if(!defined $nicknames{$nickname})
    {
	Irssi::print("I do not know the password for this nickname. Please add it to identify-md5.pl.");
	return;
    }

    # Well, let's ask NickServ for a cookie then
    $server->command("QUOTE NickServ identify-md5");
}

sub event_notice
{
    my ($server, $text, $nick, $address) = @_;

    # Just ignore it if we are not on SorceryNet
    return unless $server->{'real_address'} =~ /\.sorcery\.net$/;

    # Only respond to cookies from the 'real' NickServ
    return unless $nick eq 'NickServ';

    # Get the nickname we are currently using
    my $nickname = lc $server->{'nick'};

    # Is it a cookie?
    if($text =~ /^205 S\/MD5 1\.0 (.+)$/)
    {
	my $cookie = $1;
	my $password;

	# Do this check again, just to be sure
	if(!defined $nicknames{$nickname})
	{
	    Irssi::print("I do not know the password for this nickname. Please add it to identify-md5.pl.");
	}
	else
	{
	    $password = $nicknames{$nickname};

	    # Create the hash and send it
	    my $hash = md5_hex("$nickname:$cookie:$password");
	    $server->command("QUOTE NickServ identify-md5 $nickname $hash");
	}

	# Suppress the notice from NickServ
	Irssi::signal_stop();
    }

    # Is it a response?
    elsif($text =~ /^\d{3} \- (.+)$/)
    {
	my $response = $1;

	# Just print the text-part and suppress the notice
	Irssi::print($response);
	Irssi::signal_stop();
    }

    # Identify when NickServ asks us to
    elsif(defined $nicknames{$nickname} && $text =~ /^This nick belongs to another user\./)
    {
	$server->command("identify-md5");

	# And suppress the notice
	Irssi::signal_stop();
    }

    # Just ignore this notice, we already identify when receiving the other one
    elsif(defined $nicknames{$nickname} && $text eq 'If this is your nick please try: /msg NickServ ID password')
    {
	Irssi::signal_stop();
    }
}

Irssi::command_bind('identify-md5', 'cmd_identify');
Irssi::signal_add('message irc notice', 'event_notice');
