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..989e3ef --- /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. + +        $/ = "\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. + +        $/ = "\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); | 
