Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
use strict;
use vars qw($VERSION %IRSSI);
use Irssi;
use Storable qw/freeze thaw/;
use Compress::Zlib;
use Crypt::CBC;
use Crypt::Cipher::AES;
use File::Glob ':bsd_glob';
use CPAN::Meta::YAML;
$VERSION = '0.01';
%IRSSI = (
authors => 'bw1',
contact => 'bw1@aol.at',
name => 'matryoshka',
description => 'a password matryoshka',
license => 'Public Domain',
url => 'https://scripts.irssi.org/',
changed => '2019-12-03',
modules => 'Storable Compress::Zlib Crypt::CBC Crypt::Cipher::AES File::Glob '.
'CPAN::Meta::YAML',
commands=> 'matryoshka',
);
my $help = << "END";
%9Name%9
$IRSSI{name}
%9Version%9
$VERSION
%9description%9
$IRSSI{description}
%9example%9
/matryoshka expando add mynet /msg -mynet nickserv IDENTIFY account password
/network add -autosendcmd '\$mynet' mynet
/matryoshka startup add /connect ircserver port password nick
%9Settings%9
%Umatryoshka_file%U
%Umatryoshka_key%U
%Umatryoshka_key_file%U
%9Commands%9
%Usave%U
%Udump%U
%Uexpando%U
list
add <expando name> <string>
remove <expando name>
update
%Ustartup%U
list
add <command string>
remove <number>
run
%Uhelp%U
%9Warning%9
The passwords are not save in this store!
END
my ($matryoshka_file, $matryoshka_key, $matryoshka_key_file);
my $db;
my $change=0;
my $key;
my %expandos;
my %expandosf;
sub cmd {
my ($args, $server, $witem)=@_;
my @args = split /\s+/,$args;
my $arg = shift @args;
my $cmd=0;
if ( $arg eq 'save') {
$change=1;
savekeyfile();
savefile();
$cmd++;
}
if ( $arg eq 'dump') {
cmd_dump($server, $witem, @args);
$cmd++;
}
if ( $arg eq 'expando' ) {
scmd_expando($server, $witem, @args);
$cmd++;
}
if ( $arg eq 'startup' ) {
scmd_startup($server, $witem, @args);
$cmd++;
}
if ( $arg eq 'help' || $cmd == 0 ) {
Irssi::print($help, MSGLEVEL_CLIENTCRAP);
}
}
sub scmd_startup {
my ($server, $witem, @args)=@_;
my $arg= shift @args;
if ($arg eq 'list') {
sscmd_s_list($server, $witem, @args);
}
if ($arg eq 'add') {
sscmd_s_add($server, $witem, @args);
}
if ($arg eq 'remove') {
sscmd_s_remove($server, $witem, @args);
}
if ($arg eq 'run') {
startup_run();
}
}
sub sscmd_s_list {
my ($server, $witem, @args)=@_;
if (exists $db->{startup} ) {
my $c=1;
foreach (@{$db->{startup}}) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'startup_theme',
$c, $_ );
$c++;
}
}
}
sub sscmd_s_add {
my ($server, $witem, @args)=@_;
if (!exists $db->{startup} ) {
$db->{startup}=[];
}
push @{$db->{startup}}, join(" ", @args);
$change=1;
}
sub sscmd_s_remove {
my ($server, $witem, @args)=@_;
my $ex= shift @args;
splice @{$db->{startup}}, $ex-1, 1;
$change=1;
}
sub startup_run {
if (exists $db->{startup} ) {
foreach (@{$db->{startup}}) {
Irssi::command($_);
}
}
}
sub scmd_expando {
my ($server, $witem, @args)=@_;
my $arg= shift @args;
if ($arg eq 'list') {
sscmd_e_list($server, $witem, @args);
}
if ($arg eq 'add') {
sscmd_e_add($server, $witem, @args);
}
if ($arg eq 'remove') {
sscmd_e_remove($server, $witem, @args);
}
if ($arg eq 'update') {
updateexpandos();
}
}
sub sscmd_e_list {
my ($server, $witem, @args)=@_;
if (exists $db->{expando} ) {
foreach (sort keys %{$db->{expando}}) {
Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'expando_theme',
$_, $db->{expando}->{$_});
}
}
}
sub sscmd_e_add {
my ($server, $witem, @args)=@_;
if (!exists $db->{expando} ) {
$db->{expando}={};
}
my $ex= shift @args;
$db->{expando}->{$ex}= join " ", @args;
$change=1;
}
sub sscmd_e_remove {
my ($server, $witem, @args)=@_;
my $ex= shift @args;
delete $db->{expando}->{$ex};
$change=1;
}
sub cmd_dump {
my ($server, $witem, @args)=@_;
my $yml= CPAN::Meta::YAML->new;
push @$yml, $db;
print $yml->write_string;
}
sub cmd_help {
my ($args, $server, $witem)=@_;
$args=~ s/\s+//g;
if ($IRSSI{name} eq $args) {
Irssi::print($help, MSGLEVEL_CLIENTCRAP);
Irssi::signal_stop();
}
}
sub loadfile {
my $fn= filename($matryoshka_file);
if ( -e $fn) {
my ($serial, $comp, $cyper);
open my $fi, '<', $fn;
local $/;
$cyper= <$fi>;
close $fi;
my $cbc2 = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$key );
my $cyper2 = $cbc2->decrypt($cyper);
my $cbc = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$matryoshka_key );
$comp = $cbc->decrypt($cyper2);
$serial= uncompress( $comp );
$db= thaw($serial);
$change=0;
}
}
sub savefile {
my $fn= filename($matryoshka_file);
my $serial= freeze( $db );
my $comp;
if ($change != 0) {
$comp= compress( $serial, 9 );
my $cbc = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$matryoshka_key);
my $ciphertext = $cbc->encrypt($comp);
my $cbc2 = Crypt::CBC->new( -cipher=>'Cipher::AES', -key=>$key);
my $ciphertext2 = $cbc2->encrypt($ciphertext);
open my $fa, '>', $fn;
print $fa $ciphertext2;
close $fa;
}
}
sub loadkeyfile {
my $fn= filename($matryoshka_key_file);
if (-e $fn) {
open my $fi, '<', $fn;
local $/;
$key= <$fi>;
close $fi;
} else {
savekeyfile();
}
}
sub savekeyfile {
my $fn= filename($matryoshka_key_file);
$key= Crypt::CBC->random_bytes(16);
$change=1;
open my $fa, '>', $fn;
print $fa $key;
close $fa;
}
sub filename {
my ($fn)= @_;
if ($fn !~ m#/#) {
$fn= Irssi::get_irssi_dir().'/'.$fn;
} else {
$fn= bsd_glob($fn);
}
return $fn;
}
sub updateexpandos {
foreach (keys %{$db->{expando}}) {
if (!defined $expandos{$_}) {
my $fustr = '$expandosf{'.$_.'}= sub { return "'. $db->{expando}->{$_}.'";}';
eval($fustr);
Irssi::expando_create $_, $expandosf{$_}, { };
$expandos{$_}=2;
} else {
$expandos{$_}=2;
}
}
foreach (keys %expandos) {
if ( $expandos{$_} == 1) {
delete $expandos{$_};
Irssi::expando_destroy $_;
} else {
$expandos{$_}=1;
}
}
}
sub sig_setup_changed {
$matryoshka_file= Irssi::settings_get_str($IRSSI{name}.'_file');
$matryoshka_key= Irssi::settings_get_str($IRSSI{name}.'_key');
if ( $matryoshka_key eq '' ) {
$matryoshka_key= Crypt::CBC->random_bytes(16);
Irssi::settings_set_str($IRSSI{name}.'_key', $matryoshka_key);
$change=1;
}
$matryoshka_key_file= Irssi::settings_get_str($IRSSI{name}.'_key_file');
}
sub UNLOAD {
savefile();
}
Irssi::theme_register([
'expando_theme', '{hilight $0} $1',
'startup_theme', '{hilight $0} $1',
]);
Irssi::signal_add('setup changed', \&sig_setup_changed);
Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_file', 'matryoshka.store');
Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_key', '');
Irssi::settings_add_str($IRSSI{name} ,$IRSSI{name}.'_key_file', '.matryoshka.key.file');
Irssi::command_bind($IRSSI{name}, \&cmd);
foreach ( qw/save dump expando startup/ ){
Irssi::command_bind($IRSSI{name}.' '.$_, \&cmd);
}
foreach ( qw/list add remove update/ ){
Irssi::command_bind($IRSSI{name}.' expando '.$_, \&cmd);
}
foreach ( qw/list add remove run/ ){
Irssi::command_bind($IRSSI{name}.' startup '.$_, \&cmd);
}
Irssi::command_bind('help', \&cmd_help);
sig_setup_changed();
loadkeyfile();
loadfile();
updateexpandos();
startup_run();