html/identify-md5.pl


   1 use Irssi;
   2 use Digest::MD5 qw(md5_hex);
   3 use strict;
   4 use vars qw($VERSION %IRSSI @identify @reop);
   5 
   6 $VERSION = '1.05';
   7 %IRSSI = (
   8     authors 	=> 'Eric Jansen',
   9     contact 	=> 'chaos@sorcery.net',
  10     name 	=> 'identify-md5',
  11     description => 'MD5 NickServ identification script for SorceryNet',
  12     license 	=> 'GPL',
  13     modules	=> 'Digest::MD5',
  14     url		=> 'http://xyrion.org/irssi/',
  15     changed 	=> 'Sat Mar  1 13:32:30 CET 2003'
  16 );
  17 
  18 ################################################################################
  19 #
  20 #  MD5 NickServ identification script for SorceryNet (irc.sorcery.net)
  21 #
  22 #  The script will do several things:
  23 #  - It adds the command /identify-md5 to Irssi, which can be used to identify
  24 #    to your current nickname or a list of nicknames given as arguments using 
  25 #    the passwords provided below
  26 #  - It will automatically issue this command whenever NickServ notices you 
  27 #    that you need to identify (e.g. after a services outage)
  28 #  - It will remember any channels ChanServ deopped you in and try to regain 
  29 #    ops after authentication is accepted by NickServ
  30 #
  31 #  For more information on SorceryNets MD5 identification see:
  32 #  http://www.sorcery.net/help/howto/MD5_identify
  33 #
  34 #  Put your nicknames and MD5-hashed passwords here:
  35 #
  36 
  37 my %nicknames = (
  38     lc('nick1')		=> md5_hex('password1'), 		# Plain text password 'password1'
  39     lc('nick2')		=> '6cb75f652a9b52798eb6cf2201057c73',	# MD5-hash of password 'password2'
  40     lc('nick3')		=> md5_hex('password3')
  41 );
  42 
  43 #
  44 #  Please note: This file should NOT be world-readable. Although it's (quite) 
  45 #               impossible to get the original passwords from the hashes, a
  46 #               malicious person can identify using the hash and then change
  47 #               your password without knowing the old password.
  48 #
  49 ################################################################################
  50 
  51 sub cmd_identify {
  52 
  53     my ($data, $server, $witem) = @_;
  54 
  55     # Are we connected?
  56     if(!$server || !$server->{'connected'}) {
  57 
  58 	Irssi::print("Not connected to a server.");
  59 	return;
  60     }
  61 
  62     # Did the user specify what nick(s) to identify to?
  63     if($data ne '') {
  64 
  65 	# Store the list of nicknames to identify to then
  66 	@identify = split /\s+/, $data;
  67     }
  68     else {
  69 
  70 	# Or put our current nick on the list
  71 	push @identify, $server->{'nick'};
  72     }
  73 
  74     # Start with some checks
  75     for(my $i = $#identify; $i >= 0; $i--) {
  76 
  77 	# If we don't know the password
  78 	if(!defined $nicknames{lc $identify[$i]}) {
  79 
  80 	    # Send an error
  81 	    Irssi::print("I do not know the password for ${identify[$i]}. Please add it to identify-md5.pl.");
  82 
  83 	    # And remove the nick from the list
  84 	    splice @identify, $i, 1;
  85 	}
  86     }
  87 
  88     # Let's ask NickServ for a cookie if there are nicks left
  89     $server->command("QUOTE NickServ identify-md5") if $#identify >= 0;
  90 }
  91 
  92 sub event_notice {
  93 
  94     my ($server, $text, $nick, $address) = @_;
  95 
  96     # Just ignore it if we are not on SorceryNet
  97     return unless $server->{'real_address'} =~ /\.sorcery\.net$/;
  98 
  99     # Is it a notice from NickServ?
 100     if($nick eq 'NickServ') {
 101 
 102 	# Is it a cookie and do we need one?
 103 	if($text =~ /^205 S\/MD5 1\.0 (.+)$/ && $#identify >= 0) {
 104 
 105 	    my $cookie = $1;
 106 
 107 	    my $nickname = lc shift @identify;
 108 	    my $password = $nicknames{$nickname};
 109 
 110 	    # Create the hash and send it
 111 	    my $hash = md5_hex("$nickname:$cookie:$password");
 112 	    $server->command("QUOTE NickServ identify-md5 $nickname $hash");
 113 
 114 	    # Suppress the notice from NickServ
 115 	    Irssi::signal_stop();
 116 
 117 	    # And get a new cookie if there are still nicks left to identify to
 118 	    $server->command("QUOTE NickServ identify-md5") if $#identify >= 0;
 119 	}
 120 
 121 	# Is it a response?
 122 	elsif($text =~ /^\d{3} \- (.+)$/) {
 123 
 124 	    my $response = $1;
 125 
 126 	    # Just print the text-part and suppress the notice
 127 	    Irssi::print($response);
 128 
 129 	    if($response eq 'Authentication accepted -- you are now identified.') {
 130 
 131 		foreach my $channel (@reop) {
 132 		    $server->command("QUOTE ChanServ $channel op $server->{nick}");
 133 		}
 134 		undef @reop;
 135 	    }
 136 
 137 	    Irssi::signal_stop();
 138 	}
 139 
 140 	# Do we know the password? Let's see what NickServ has to tell us then
 141 	elsif(defined $nicknames{lc $server->{'nick'}}) {
 142 	
 143 	    # Identify when NickServ asks us to
 144 	    if($text =~ /^This nick belongs to another user\./) {
 145 
 146 		$server->command("identify-md5");
 147 		Irssi::signal_stop();
 148 	    }
 149 
 150 	    # Just ignore this notice, we already identify when receiving the other one
 151 	    elsif($text eq 'If this is your nick please try: /msg NickServ ID password') {
 152 
 153 		Irssi::signal_stop();
 154 	    }
 155 	}
 156     }
 157 
 158     # If it's ChanServ saying it just deopped us, remember the channel so we can reop
 159     elsif($nick eq 'ChanServ' && $text =~ /^You are not allowed ops in ([^\s]+)$/) {
 160 
 161 	push @reop, $1;
 162 
 163 	Irssi::signal_stop();
 164     }
 165 }
 166 
 167 Irssi::command_bind('identify-md5', 'cmd_identify');
 168 Irssi::signal_add('message irc notice', 'event_notice');