diff options
Diffstat (limited to 'scripts/xauth.pl')
-rw-r--r-- | scripts/xauth.pl | 546 |
1 files changed, 546 insertions, 0 deletions
diff --git a/scripts/xauth.pl b/scripts/xauth.pl new file mode 100644 index 0000000..c4b13c0 --- /dev/null +++ b/scripts/xauth.pl @@ -0,0 +1,546 @@ +# Some code taken from `nickserv.pl' for convenience. +# Credits Sami Haahtinen / ZaNaGa +# + +# Don't forget to create the necessary chatnets in your irssi config file. +# +# Example: +# .... +# { +# address = "irc.undernet.org"; +# chatnet = "Undernet"; +# port = "6668"; +# autoconnect = no; +# } +# ..... +# +# +# Then connect with the server like this: +# /server undernet (or set autoconnect to yes) + +# Make sure you fill in *all* necessary information without typos. +# +# Files you need to edit after first run: +# x.users -> For your x user/pw information. +# x.channels -> Channels to join after authing. (optional) +# +# Use /xrehash to reload if you edit the files. +# +# Var: +# my (%masks) -> See help there. + +# Tested with X versions +# Undernet P10 Channel Services II Release 1.1pl7 +# + +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file +# COPYING (included with this distribution) or the GNU General Public +# License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +use Irssi; +use Irssi::Irc; + +use strict; + +use vars qw($VERSION %IRSSI); + +$VERSION = '1.02'; + +%IRSSI = ( + authors => 'Toshio R. Spoor', + contact => 't.spoor@gmail.com', + name => 'xauth', + description => 'Undernet X Service Authentication Program', + license => 'GNU GPLv2 or later', + changed => '$Date: 2004/12/17 08:39:47 $' +); + +my (%CONFIG) = ( + autostart => '', + autojoin => '', + hiddenhost => '' +); + +Irssi::theme_register([ + xauth_rehash => '{comment $0} %KRehashing configuration files and settings%n', + xauth_autostart => '{comment $0} %KAuto-Start :%n $1', + xauth_autojoin => '{comment $0} %KAuto-Join :%n $1', + xauth_hiddenhost=> '{comment $0} %KHiddenhost :%n $1', + xauth_auth => '{comment $0} %KAuthorising%n $1 %Kwith%n $2 %Kon%n $3', + xauth_load => '{comment $0} %KScript %nv$1 %Kloaded ...%n', + xauth_nocon => '{comment $0} %KNot connected to server%n', + xauth_noconn => '{comment $0} %KThere does not exist a connection to $1%n', + xauth_success => '{comment $0} %KLogged in successfully on %n$1', + xauth_failed => '{comment $0} %KFailed to login on %n$1 ($2)', + xauth_already => '{comment $0} %KI am already logged in on%n $1', + xauth_nouser => '{comment $0} $1 %Kdoes not know who %n$2 %Kis on %n$3', + xauth_nohost => '{comment $0} %KNo hostmask found for %n$1%K, to fix this edit this script, see masks', + xauth_noentry => '{comment $0} %KI did not find an entry for %n$1 %Kcheck%n $2', + xauth_missing => '{comment $0} %KI am missing username, password or authentication host login information%n', + xauth_join => '{comment $0} %KJoined on%n $1%K : %n$2-' +]); + +my ($usage) = qq!X-Authentication v$VERSION by Toshio Spoor + +Usage: +/auth <chatnet> + +Settings: +/set xauth Shows current settings +/toggle xauth_autostart Toggle Auto Start +/toggle xauth_autojoin Toggle Auto Join +/toggle xauth_hiddenhost Toggle Hiddenhost (ircu u2.10.11+) + +Rehashing settings and user/channel file: +/xrehash Run this after any changes + made to settings/files + +/save Make settings permanent +!; + +# The `masks' hash is very important: +# Here we fill in the masks we need to authenticate with. +# +# <chatnet> = <host> <authhost> +# +# You can find this very easily: +# /msg x login +# +# 08:49 -!- Irssi: Starting query in Undernet with x +# 08:49 <Foo> login +# 08:49 -X(channels@undernet.org)- To use LOGIN, you must /msg X@services.undernet.org +# +# Keep the chatnet lowercase + +my (%masks) = ( + undernet => [ 'cservice@undernet.org', 'X@channels.undernet.org' ], + worldirc => [ 'cservice@worldirc.org','X@channels.worldirc.org' ] +); + +# 0 = None +# 1 = Normal +# 2 = More + +my ($verbose) = 1; + +# Don't touch these, unless the signature changes. +# +my ($success) = "AUTHENTICATION SUCCESSFUL"; +my ($already) = "Sorry, You are already authenticated"; +my ($failed) = "AUTHENTICATION FAILED"; +my ($remind) = "Remember: Nobody from CService will ever ask you for your password, do NOT give"; +my ($nouser) = "I don't know who"; + +# Global Vars, don't change these. +# +my ($x_passfile) = Irssi::get_irssi_dir() ."/x.users"; +my ($x_chanfile) = Irssi::get_irssi_dir() ."/x.channels"; + +my (@users) = (); +my (@chans) = (); + +# Core Code +# +# + +sub putlog() { + + my ($window) = Irssi::active_win(); + Irssi::print("[$IRSSI{'name'}] @_", MSGLEVEL_CLIENTNOTICE); + +} + +sub haltdef() { + + Irssi::signal_stop(); + +} + +sub conn($) { + + my ($server) = @_; + + if (!$server || !$server->{connected}) { + return 0; + } else { + return 1; + } + +} + +sub join_channels($) { + + my ($chatnet) = @_; + my (@channels) = (); + my ($server) = Irssi::server_find_tag($chatnet); + + if (!$server) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_nocon", "$IRSSI{'name'}"); + return; + } + + foreach (@chans) { + + my ($channel, $ircnet) = split(/:/); + + if (lc($chatnet) eq lc($ircnet)) { + # If we do it like this, the status window stays active. + push (@channels, $channel); + $server->send_raw("JOIN #$channel"); + } + } + + if ($verbose) { + if (@channels) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_join", "$IRSSI{'name'}", $chatnet, @channels); + } + } +} + +sub mask_check($) { + + my ($address) = @_; + + foreach my $key (keys %masks) { + if (lc($masks{$key}->[0]) eq lc($address)) { + return $key; + last; + } + } + + return 0; + +} + + +sub event_notice() { + + my ($server, $args, $nick, $nickad) = @_; + + return unless (&mask_check($nickad)); + + my ($cnet) = $server->{'tag'}; + my ($version) = $server->{'version'}; + + my ($target, $data) = $args =~ /^(\S*)\s+:(.*)$/; + + $_ = $data; + + if (/^$already/i) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_already", "$IRSSI{'name'}", $cnet); + &haltdef(); + } + + if (/^$success/i) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_success", "$IRSSI{'name'}", $cnet); + + if (($version) && ($CONFIG{'hiddenhost'})) { + + my($app,$hi,$lo) = $version =~ /^(..).(..).(..)/; + $app =~ s/\D//g; + + if (($app >= 2) && ($lo >= 11)) { + &putlog("Found ircu $version, setting umode +x") if ($verbose > 1); + $server->command("mode $target +x"); + } + } + + if ($CONFIG{'autojoin'}) { + &join_channels($cnet); + } + &haltdef(); + } + + if (/^$failed/i) { + if (/\((.*?)\)/) { $args = $1 }; + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_failed", "$IRSSI{'name'}", $cnet, $args); + &haltdef(); + } + + if (/^$remind/i) { + &haltdef(); + } + + if (/^$nouser/i) { + if (/who\s(.*?)\s/) { $args = $1 }; + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_nouser", "$IRSSI{'name'}", "$nick", $args, $cnet); + &haltdef(); + } +} + +sub cmd_auth() { + + my ($data, $server, $witem) = @_; + my ($username, $ircnet, $password, $xlogin, $xmask, $chatnet, $found); + + if ($data) { + $chatnet = $data; + } else { + &putlog("$usage"); + return; + } + + if (! &conn($server)) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_nocon", "$IRSSI{'name'}"); + return; + } + + my ($authserver) = Irssi::server_find_tag($chatnet); + + if (! $authserver) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_noconn", "$IRSSI{'name'}", $chatnet); + return; + } + + foreach (@users) { + + ($username, $ircnet, $password) = split(/:/); + + if (lc($ircnet) eq lc($chatnet)) { + $xmask = $masks{lc($ircnet)}->[0]; + $xlogin = $masks{lc($ircnet)}->[1]; + + if ((!$xmask) || (!$xlogin)) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_nohost", "$IRSSI{'name'}", $chatnet); + return; + } + + $found=1; + last; + } + } + + if (! $found ) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_noentry", "$IRSSI{'name'}", $chatnet, qq/"$x_passfile"/); + return; + } + + if (($username) && ($password) && ($xlogin)) { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_auth", "$IRSSI{'name'}", $username, $xlogin, $chatnet); + $authserver->send_raw("PRIVMSG $xlogin :login $username $password"); + } else { + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_missing", "$IRSSI{'name'}"); + } +} + +# Code taken from nickserv.pl + +sub read_users() { + my $count = 0; + + # Lets reset @users so we can call this as a function. + @users = (); + + if (!(open XUSERS, "<", $x_passfile)) { + &create_users; + }; + &putlog("Running checks on the userfile.") if ($verbose > 1); + # first we test the file with mask 066 (we don't actually care if the + # file is executable by others.. what could they do with it =) + + # Well, according to my calculations umask 066 should be 54, go figure. + + my $mode = (stat($x_passfile))[2]; + if ($mode & 54) { + &putlog("your password file should be mode 0600. Go fix it!"); + &putlog("use command: chmod 0600 $x_passfile"); + } + + # and then we read the userfile. + # apparently Irssi resets $/, so we set it here. + + local $/ = "\n"; + while( my $line = <XUSERS>) { + if( $line !~ /^(#|\s*$)/ ) { + my ($nick, $ircnet, $password) = + $line =~ /^\s*(\S+)\s+(\S+)\s+(.*?)$/; + push @users, "$nick:$ircnet:$password"; + $count++; + } + } + &putlog("Found $count accounts") if ($verbose > 1); + close XUSERS; +} + +sub create_users() { + + &putlog("Creating basic userfile in $x_passfile. Edit File."); + + if(!(open XUSERS, ">", $x_passfile)) { + &putlog("Unable to create file $x_passfile"); + } + + print XUSERS "# username and IrcNet Tag are case insensitive\n"; + print XUSERS "#\n"; + print XUSERS "# username IrcNet Tag Password\n"; + print XUSERS "# -------- ---------- --------\n"; + + close XUSERS; + chmod 0600, $x_passfile; +} + +sub create_chans() { + &putlog("Creating basic channelfile in $x_chanfile. Edit File."); + if(!(open NICKCHANS, ">", $x_chanfile)) { + &putlog("Unable to create file $x_chanfile"); + } + + print NICKCHANS "# This file should contain a list of all channels\n"; + print NICKCHANS "# which you don't want to join until after you've\n"; + print NICKCHANS "# successfully identified with x. This is\n"; + print NICKCHANS "# useful if you have a hidden host (+x).\n"; + print NICKCHANS "# Enter Channel without `#'\n"; + print NICKCHANS "#\n"; + print NICKCHANS "# Channel IrcNet Tag\n"; + print NICKCHANS "# -------- ----------\n"; + + close NICKCHANS; + chmod 0600, $x_chanfile; +} + +sub read_chans() { + my $count = 0; + + # Lets reset @users so we can call this as a function. + @chans = (); + + if (!(open NICKCHANS, "<", $x_chanfile)) { + create_chans; + }; + &putlog("Running checks on the channelfile.") if ($verbose > 1); + # first we test the file with mask 066 (we don't actually care if the + # file is executable by others.. what could they do with it =) + + # Well, according to my calculations umask 066 should be 54, go figure. + + my $mode = (stat($x_chanfile))[2]; + if ($mode & 54) { + &putlog("your channels file should be mode 0600. Go fix it!"); + &putlog("use command: chmod 0600 $x_chanfile"); + } + + # and then we read the channelfile. + # apparently Irssi resets $/, so we set it here. + + local $/ = "\n"; + while( my $line = <NICKCHANS>) { + if( $line !~ /^(#|\s*$)/ ) { + my ($channel, $ircnet) = + $line =~ /\s*(\S+)\s+(\S+)/; + push @chans, "$channel:$ircnet"; + $count++; + } + } + &putlog("Found $count channels") if ($verbose > 1); + close NICKCHANS; +} + +# End code from nickserv.pl + +sub event_connect() { + + $CONFIG{'autostart'} = Irssi::settings_get_bool('xauth_autostart'); + + return unless ($CONFIG{'autostart'}); + + my ($server) = @_; + my ($cnet) = $server->{'tag'}; + my ($found); + + foreach my $key (keys %masks) { + if (lc($key) eq lc($cnet)) { + $found=1; + last; + } + } + + return unless($found); + + $server->command("auth $cnet"); + +} + +sub x_rehash() { + + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_rehash", "$IRSSI{'name'}") if (($verbose) && (@_)); + + &read_users(); + &read_chans(); + &get_set(@_); + +} + +sub init_set() { + + Irssi::settings_add_bool('misc', 'xauth_autostart', '0'); + Irssi::settings_add_bool('misc', 'xauth_autojoin', '1'); + Irssi::settings_add_bool('misc', 'xauth_hiddenhost','0'); + +} + +sub onoff($) { + + my ($value) = @_; + + if ($value) { + return "On"; + } else { + return "Off"; + } + +} + +sub get_set() { + + $CONFIG{'autostart'} = Irssi::settings_get_bool('xauth_autostart'); + $CONFIG{'autojoin'} = Irssi::settings_get_bool('xauth_autojoin'); + $CONFIG{'hiddenhost'} = Irssi::settings_get_bool('xauth_hiddenhost'); + + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_autostart", "$IRSSI{'name'}", &onoff("$CONFIG{'autostart'}")) if (($verbose) && (@_)); + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_autojoin", "$IRSSI{'name'}", &onoff("$CONFIG{'autojoin'}")) if (($verbose) && (@_)); + Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_hiddenhost", "$IRSSI{'name'}", &onoff("$CONFIG{'hiddenhost'}")) if (($verbose) && (@_)); + +} + +sub init() { + + &init_set(); + &x_rehash(); + + +} + +sub x_help() { + + &putlog("$usage"); + +} + + +# Main +# +# + +&init(); + +Irssi::command_bind("auth", "cmd_auth"); +Irssi::command_bind("xrehash", "x_rehash"); +Irssi::command_bind("xhelp", "x_help"); + +Irssi::signal_add("event notice", "event_notice"); +Irssi::signal_add("event connected", "event_connect"); + +Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "xauth_load", "$IRSSI{'name'}", $VERSION); |