1use Irssi; 2use Digest::MD5 qw(md5_hex); 3use strict; 4use 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 37my %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 51sub 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 92sub 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 167Irssi::command_bind('identify-md5', 'cmd_identify'); 168Irssi::signal_add('message irc notice', 'event_notice'); 169