summaryrefslogtreecommitdiffstats
path: root/scripts/xauth.pl
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/xauth.pl')
-rw-r--r--scripts/xauth.pl546
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);