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');