From 2d0759e6ca5767b48bcc85bf38c2c43d5f0b63b1 Mon Sep 17 00:00:00 2001 From: Alexander Færøy Date: Sat, 31 May 2014 13:10:46 +0200 Subject: Import scripts from scripts.irssi.org --- scripts/securemsg.pl | 509 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 scripts/securemsg.pl (limited to 'scripts/securemsg.pl') diff --git a/scripts/securemsg.pl b/scripts/securemsg.pl new file mode 100644 index 0000000..c719482 --- /dev/null +++ b/scripts/securemsg.pl @@ -0,0 +1,509 @@ +# Thanks to Geert and Karl "Sique" Siegemund on their work on the whitelist.pl script that is the basis for my work. +# +# Supports multiple servers +# +# /set securemsg_nicks phyber etc +# nicks that are allowed to msg us (whitelist checks for a valid nick before a valid host) +# +# /set securemsg_hosts *!*@*isp.com *!ident@somewhere.org +# Hosts that are allowed to message us, space delimited +# +# /sm add nick +# puts new nicks into the whitelist_nicks list +# +# /sm add host +# puts new hosts into the whitelist_hosts list +# +# /sm del nick +# removes the nicks from whitelist_nicks +# +# /sm del host +# removes the hosts from whitelist_hosts +# +# /sm nicks +# shows the current whitelist_nicks +# +# /sm hosts +# shows the current whitelist_hosts +# +# /sm accept [message] +# accept chat from nick +# +# /sm reject [message] +# reject chat from nick +# +# /sm clear +# clears messages from nick without ignoring +# +## + +use strict; +use Irssi; +use Irssi::Irc; +use Irssi::UI; +use Irssi::TextUI; + + +use vars qw($VERSION %IRSSI); +$VERSION = "2.1"; +my $APPVERSION = "Securemsg v2.1"; +%IRSSI = ( + authors => "Jari Matilainen, a lot of code borrowed from whitelist.pl by David O\'Rourke and Karl Siegemund", + contact => "vague`!#irssi\@freenode on irc ", + name => "securemsg", + description => "An irssi adaptation of securequery.mrc found in the Acidmax mIRC script. :), now with multiserver support", + licence => "GPLv2", + changed => "10.09.2007 11:30pm GST" +); + +my $whitenick; +my $whitehost; +my $tstamp; +my %messages = (); + +# A mapping to convert simple regexp (* and ?) into Perl regexp +my %htr = ( ); +foreach my $i (0..255) { + my $ch = chr($i); + $htr{$ch} = "\Q$ch\E"; +} +$htr{'?'} = '.'; +$htr{'*'} = '.*'; + +# A list of settings we can use and change +my %types = ( 'nicks' => 'securemsg_nicks', + 'hosts' => 'securemsg_hosts' ); + +sub lc_host($) { + my ($host) = @_; + $host =~ s/(.+)\@(.+)/sprintf("%s@%s", $1, lc($2));/eg; + return $host; +} + +sub timestamp { + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + my @timestamp = ($year+1900,$mon+1,$mday,$hour,$min,$sec); + if($timestamp[1]<10) { + $timestamp[1] = "0".$timestamp[1]; + } + if($timestamp[2]<10) { + $timestamp[2] = "0".$timestamp[2]; + } + if($timestamp[3]<10) { + $timestamp[3] = "0".$timestamp[3]; + } + if($timestamp[4]<10) { + $timestamp[4] = "0".$timestamp[4]; + } + $tstamp = "$timestamp[0]/$timestamp[1]/$timestamp[2] $timestamp[3]:$timestamp[4] "; +} + +# This one gets called from IRSSI if we get a private message (PRIVMSG) +sub securemsg_check { + my ($server, $msg, $nick, $address) = @_; + my $nicks = Irssi::settings_get_str('securemsg_nicks'); + my $hosts = Irssi::settings_get_str('securemsg_hosts'); + my $mmsg = Irssi::settings_get_str('securemsg_customhold'); + my $hostmask = "$nick!$address"; + $nick = lc($nick); + return if $server->ignore_check($nick,"","","",MSGLEVEL_MSGS); + + # Are we already talking? + return if $server->query_find($nick); + return if $server->{nick} eq $nick; + + # Nicks are the easiest to handle with the least computational effort. + # So do them before hosts and networks. + foreach my $whitenick (split(/\s+/, "$nicks")) { + $nick = lc($nick); + $whitenick = lc($whitenick); + # Simple check first: Is the nick itself whitelisted? + return if ($nick eq $whitenick); + } + + # Hostmasks are somewhat more sophisticated, because they allow wildcards + foreach my $whitehost (split(/\s+/, "$hosts")) { + # Allow if the hostmask matches + return if $server->mask_match_address($whitehost,"*",$hostmask); + } + + # stop if the message isn't from a whitelisted address + # print a notice if that setting is enabled + # this could flood your status window if someone is flooding you with messages + + if ((!defined $mmsg) || ($mmsg eq " ") || ($mmsg eq "")) { + $mmsg = "Please standby for acknowledgement. I am using «$APPVERSION» for irssi. You will be notified if accepted. Until then your messages will be ignored."; + } + else { + $mmsg = $mmsg." «$APPVERSION»"; + } + + $server->command("^NOTICE $nick $mmsg") if(!exists $messages{$nick}{$server->{tag}}); + + #Save message from $nick + timestamp(); + my $channel; + my @channels = $server->channels(); + foreach my $chan (@channels) { + if($chan->nick_find_mask($nick)) { + $channel = $chan; + last; + } + } + + my $tmpmsg = $tstamp."<".$nick."!".(($channel)?$channel->{name}:"none")."@".lc($server->{tag})."> ".$msg; + push @{$messages{$nick}{lc($server->{tag})}{messages}},$tmpmsg; + + refresh_securemsg(); + Irssi::command_bind("sm accept $nick",\&cmd_accept); + Irssi::command_bind("sm reject $nick",\&cmd_reject); + Irssi::command_bind("sm accept $nick net",\&cmd_accept); + Irssi::command_bind("sm reject $nick net",\&cmd_reject); + Irssi::command_bind("sm accept $nick net ".lc($server->{tag}),\&cmd_accept); + Irssi::command_bind("sm reject $nick net ".lc($server->{tag}),\&cmd_reject); + Irssi::command_bind("sm show $nick",\&cmd_show); + Irssi::command_bind("sm show $nick net ",\&cmd_show); + Irssi::command_bind("sm show $nick net ".lc($server->{tag}),\&cmd_show); + Irssi::signal_stop(); + return; +} + +sub usage { + print("Usage: sm add|del | list of nicks/hosts | sm nicks|hosts | sm accept|reject [net ] [message] | sm show [net ] | sm help"); +} + +sub cmd_accept { + my ($args, $active_server, $witem) = @_; + my ($nick, $rest) = split /\s+/, $args, 2; + my ($arg, $net); + my $server; + my $mmsg = Irssi::settings_get_str('securemsg_customaccept'); + my $msg; + + if($rest =~ /^net/) { + ($arg, $net, $rest) = split /\s+/, $rest, 3; + } + + $nick = lc($nick); + $net = lc($net); + + if((!defined $nick) || ($nick eq "")) { + usage; + return; + } + + return if(!exists $messages{$nick}); + + if((!defined $rest) || ($rest eq " ") || ($rest eq "")) { + if((!defined $mmsg) || ($mmsg eq " ") || ($mmsg eq "")) { + $rest = "Hold on, I'm switching windows..."; + } + else { + $rest = $mmsg; + } + } + + if(defined $net && !(($net eq " ") || ($net eq ""))) { + foreach (keys %{$messages{$nick}}) { + if(lc($_) eq $net) { + $server = Irssi::server_find_tag($_); + last; + } + } + } + elsif(keys(%{$messages{$nick}}) == 1) { + foreach (keys %{$messages{$nick}}) { + $server = Irssi::server_find_tag($_); + } + } + else { + print("You have to specify a chatnet, for example /sm accept john net EFNet"); + return; + } + + $server->command("MSG $nick $rest"); + + my $query = $server->query_find($nick); + $query->set_active(); + foreach $msg (@{$messages{$nick}{lc($server->{tag})}{messages}}) { + $query->print("%B-%W!%B-%n $msg", MSGLEVEL_CLIENTCRAP); + } + + if(keys(%{$messages{$nick}}) > 1) { + delete $messages{$nick}{lc($server->{tag})}; + } + else { + delete $messages{$nick}; + } + + Irssi::command_unbind("sm accept $nick",\&cmd_accept); + Irssi::command_unbind("sm reject $nick",\&cmd_reject); + Irssi::command_unbind("sm accept $nick net",\&cmd_accept); + Irssi::command_unbind("sm reject $nick net",\&cmd_reject); + Irssi::command_unbind("sm accept $nick net ".lc($server->{tag}),\&cmd_accept); + Irssi::command_unbind("sm reject $nick net ".lc($server->{tag}),\&cmd_reject); + Irssi::command_unbind("sm show $nick",\&cmd_show); + Irssi::command_unbind("sm show $nick net ",\&cmd_show); + Irssi::command_unbind("sm show $nick net ".lc($server->{tag}),\&cmd_show); + refresh_securemsg(); +} + +sub cmd_reject { + my ($args, $active_server, $winit) = @_; + my ($nick, $rest) = split /\s+/, $args, 2; + my $time = Irssi::settings_get_str('securemsg_ignoretime'); + my ($arg, $net); + my $server; + + if($rest =~ /^net/) { + ($arg, $net, $rest) = split /\s+/, $rest, 3; + } + + if((!defined $time) || ($time eq "") || ($time eq " ")) { + $time = "600"; + } + + $nick = lc($nick); + $net = lc($net); + + if((!defined $nick) || ($nick eq "")) { + usage; + return; + } + + if(defined $net && !(($net eq " ") || ($net eq ""))) { + foreach (keys %{$messages{$nick}}) { + if(lc($_) eq $net) { + $server = Irssi::server_find_tag($_); + last; + } + } + } + elsif(keys(%{$messages{$nick}}) == 1) { + foreach (keys %{$messages{$nick}}) { + $server = Irssi::server_find_tag($_); + } + } + else { + print("You have to specify a chatnet, for example /sm reject john net EFNet"); + return; + } + + if((defined $rest) && !(($rest eq " ") || ($rest eq ""))) { + $server->command("^NOTICE $nick $rest"); + } + + if(keys(%{$messages{$nick}}) > 1) { + delete $messages{$nick}{lc($server->{tag})}; + } + else { + delete $messages{$nick}; + } + + Irssi::command_unbind("sm accept $nick",\&cmd_accept); + Irssi::command_unbind("sm reject $nick",\&cmd_reject); + Irssi::command_unbind("sm accept $nick net",\&cmd_accept); + Irssi::command_unbind("sm reject $nick net",\&cmd_reject); + Irssi::command_unbind("sm accept $nick net ".lc($server->{tag}),\&cmd_accept); + Irssi::command_unbind("sm reject $nick net ".lc($server->{tag}),\&cmd_reject); + Irssi::command_unbind("sm show $nick",\&cmd_show); + Irssi::command_unbind("sm show $nick net ",\&cmd_show); + Irssi::command_unbind("sm show $nick net ".lc($server->{tag}),\&cmd_show); + $server->command("^IGNORE -time $time $nick MSGS DCCMSGS NOTICES"); + refresh_securemsg(); +} + +sub cmd_add { + my ($args, $server, $witem) = @_; + my $str = ''; + my @list = ( ); + my ($type, $rest) = split /\s+/, $args, 2; + + # What type of settings we want to change? + if (($type eq "nick") || ($type eq "host")) { + $type = $type."s"; + } + my $settings = $types{$type}; + + # If we didn't get a syntactically correct command, put out an error + if(!defined $settings && defined $type) { + usage; + return; + } + + # Get the current value of the setting we want to change + my $str = Irssi::settings_get_str($settings) if defined $settings; + # What are we doing? + # Add the list to the end + $str .= " $rest"; + # Convert into an array + @list = split /\s+/, $str; + # Make the array unique (see Perl FAQ) + undef my %saw; + @list = grep(!$saw{$_}++, @list); + # Put the array together + $str = join ' ', @list; + + print "SecureMsg ${type}: $str"; + Irssi::settings_set_str($settings, $str); +} + +sub cmd_del { + my ($args, $server, $witem) = @_; + my @list = ( ); + my ($type, $rest) = split /\s+/, $args, 2; + + # What type of settings we want to change? + if (($type eq "nick") || ($type eq "host")) { + $type = $type."s"; + } + my $settings = $types{$type}; + + # If we didn't get a syntactically correct command, put out an error + if(!defined $settings && defined $type) { + usage; + return; + } + + my $str = Irssi::settings_get_str($settings); + + # Convert the list into an array + @list = split /\s+/, $str; + # Escape all letters to protect the Perl Regexp special characters + $rest =~ s/(.)/$htr{$1}/g; + # Convert the removal list into a Perl regexp + $rest =~ s/\s+/$|^/g; + # Use grep() to filter out all occurences of the removal list + $str = join(' ', grep {!/^$rest$/} @list); + + print "SecureMsg ${type}: $str"; + Irssi::settings_set_str($settings, $str); +} + +sub cmd_nicks { + print "SecureMsg nicks: ".Irssi::settings_get_str($types{nicks}); +} + +sub cmd_hosts { + print "SecureMsg hosts: ".Irssi::settings_get_str($types{hosts}); +} + +sub cmd_help { +# usage; + print ( <| - ADDS/DELETES A SPACE SEPARATED LIST OF NICKS OR HOSTS +SM NICKS|HOSTS - DISPLAYS THE CURRENT WHITELISTED NICKS OR HOSTS +SM ACCEPT [net ] [message] - ALLOWS MSG'S FROM nick +SM REJECT [net ] [message] - DOESN'T ALLOW MESSAGES FROM nick +SM SHOW [net ] - SHOWS CURRENT MESSAGES FROM nick WITHOUT ACCEPTING OR REJECTING nick +EOF + ); +} + +sub cmd_show { + my ($args, $server, $witem) = @_; + my ($nick, $rest) = split /\s+/, $args, 2; + my ($arg, $net); + my $server; + + if($rest =~ /^net/) { + ($arg, $net) = split /\s+/, $rest, 2; + } + + $net = lc($net); + + if((!defined $nick) || (!exists $messages{$nick})) { + usage; + return; + } + + if(defined $net && !(($net eq " ") || ($net eq ""))) { + foreach (keys %{$messages{$nick}}) { + if($_ eq $net) { + $server = Irssi::server_find_tag($_); + last; + } + } + } + elsif(keys(%{$messages{$nick}}) == 1) { + foreach (keys %{$messages{$nick}}) { + $server = Irssi::server_find_tag($_); + } + } + else { + print("You have to specify a chatnet, for example /sm reject john net EFNet"); + return; + } + + foreach my $msg (@{$messages{$nick}{lc($server->{tag})}{messages}}) { + print CLIENTCRAP "%B-%W!%B-%n $msg"; + } +} + +sub securemsg { + my ($item,$get_size_only) = @_; + my $result = 0; + my $nicks = ""; + foreach my $nick (keys %messages) { + foreach my $tag (keys %{$messages{$nick}}) { + if ($nicks eq "") { + if(keys %{$messages{$nick}} > 1) { + $nicks = $nick."@".$tag; + } + else { + $nicks = $nick; + } + } + else { + if(keys %{$messages{$nick}} > 1) { + $nicks = $nicks.", ".$nick."@".$tag; + } + else { + $nicks = $nicks.", ".$nick; + } + } + $result++; + } + } + if ($result ne 0) { + $result = $result." - \%_$nicks\%_"; + } + $item->default_handler($get_size_only, undef, $result, 0); +} + +sub refresh_securemsg { + Irssi::statusbar_items_redraw('securemsg'); +} + +foreach (keys(%types)) { + Irssi::settings_add_str('SecureMsg', $types{$_}, ''); +} + +Irssi::settings_add_str('Securemsg', 'securemsg_customhold', ''); +Irssi::settings_add_str('Securemsg', 'securemsg_customaccept', ''); +Irssi::settings_add_str('Securemsg', 'securemsg_ignoretime', ''); + +Irssi::signal_add_first('message private', \&securemsg_check); +Irssi::statusbar_item_register('securemsg', '{sb msgs: $0-}', 'securemsg'); + +Irssi::command_bind 'sm' => sub { + my ( $data, $server, $item ) = @_; + $data =~ s/\s+$//g; + Irssi::command_runsub ('sm', $data, $server, $item ) ; +}; +Irssi::command_bind('sm add',\&cmd_add); +Irssi::command_bind('sm del',\&cmd_del); +Irssi::command_bind('sm nicks',\&cmd_nicks); +Irssi::command_bind('sm hosts',\&cmd_hosts); +Irssi::command_bind('sm show',\&cmd_show); +Irssi::command_bind('sm accept',\&cmd_accept); +Irssi::command_bind('sm reject',\&cmd_reject); +Irssi::command_bind('sm help',\&cmd_help); +Irssi::command_bind('sm add host',\&cmd_add); +Irssi::command_bind('sm add nick',\&cmd_add); +Irssi::command_bind('sm del host',\&cmd_del); +Irssi::command_bind('sm del nick',\&cmd_del); + +refresh_securemsg(); -- cgit v1.2.3