From 0c16d85f47d645fab7c5dfc55ad45c7044467e48 Mon Sep 17 00:00:00 2001 From: Lisa Marie Maginnis Date: Sun, 14 Sep 2014 15:34:05 -0400 Subject: [PATCH] Initial commit --- README.Debian | 6 + README.source | 10 + changelog | 5 + compat | 1 + control | 17 + copyright | 49 ++ docs | 2 + files | 1 + rules | 14 + source/format | 1 + spd-perl.debhelper.log | 22 + spd-perl.dirs | 4 + spd-perl.substvars | 2 + spd-perl/DEBIAN/control | 13 + spd-perl/DEBIAN/md5sums | 17 + spd-perl/usr/bin/spd | 718 ++++++++++++++++++ .../lib/perl/5.18.2/SPD/deleting_column.pm | 164 ++++ spd-perl/usr/lib/perl/5.18.2/SPD/exporting.pm | 57 ++ spd-perl/usr/lib/perl/5.18.2/SPD/importing.pm | 81 ++ .../usr/lib/perl/5.18.2/SPD/unix_adding.pm | 122 +++ .../lib/perl/5.18.2/SPD/unix_create_config.pm | 503 ++++++++++++ .../usr/lib/perl/5.18.2/SPD/unix_editing.pm | 95 +++ .../lib/perl/5.18.2/SPD/unix_print_results.pm | 324 ++++++++ spd-perl/usr/share/doc/spd-perl/NEWS.gz | Bin 0 -> 151 bytes spd-perl/usr/share/doc/spd-perl/README | 9 + spd-perl/usr/share/doc/spd-perl/README.Debian | 6 + .../share/doc/spd-perl/changelog.Debian.gz | Bin 0 -> 167 bytes spd-perl/usr/share/doc/spd-perl/copyright | 49 ++ spd-perl/usr/share/man/de/man1/spd.1.gz | Bin 0 -> 3311 bytes spd-perl/usr/share/man/de/man5/spd.conf.5.gz | Bin 0 -> 3912 bytes spd-perl/usr/share/man/man1/spd.1.gz | Bin 0 -> 3199 bytes spd-perl/usr/share/man/man5/spd.conf.5.gz | Bin 0 -> 3590 bytes 32 files changed, 2292 insertions(+) create mode 100644 README.Debian create mode 100644 README.source create mode 100644 changelog create mode 100644 compat create mode 100644 control create mode 100644 copyright create mode 100644 docs create mode 100644 files create mode 100755 rules create mode 100644 source/format create mode 100644 spd-perl.debhelper.log create mode 100644 spd-perl.dirs create mode 100644 spd-perl.substvars create mode 100644 spd-perl/DEBIAN/control create mode 100644 spd-perl/DEBIAN/md5sums create mode 100755 spd-perl/usr/bin/spd create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/deleting_column.pm create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/exporting.pm create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/importing.pm create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/unix_adding.pm create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/unix_create_config.pm create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/unix_editing.pm create mode 100644 spd-perl/usr/lib/perl/5.18.2/SPD/unix_print_results.pm create mode 100644 spd-perl/usr/share/doc/spd-perl/NEWS.gz create mode 100644 spd-perl/usr/share/doc/spd-perl/README create mode 100644 spd-perl/usr/share/doc/spd-perl/README.Debian create mode 100644 spd-perl/usr/share/doc/spd-perl/changelog.Debian.gz create mode 100644 spd-perl/usr/share/doc/spd-perl/copyright create mode 100644 spd-perl/usr/share/man/de/man1/spd.1.gz create mode 100644 spd-perl/usr/share/man/de/man5/spd.conf.5.gz create mode 100644 spd-perl/usr/share/man/man1/spd.1.gz create mode 100644 spd-perl/usr/share/man/man5/spd.conf.5.gz diff --git a/README.Debian b/README.Debian new file mode 100644 index 0000000..9ca1cb1 --- /dev/null +++ b/README.Debian @@ -0,0 +1,6 @@ +spd for Debian +-------------- + + + + -- unknown Sun, 14 Sep 2014 10:38:11 -0400 diff --git a/README.source b/README.source new file mode 100644 index 0000000..8fa2754 --- /dev/null +++ b/README.source @@ -0,0 +1,10 @@ +spd for Debian +-------------- + + + + + + -- unknown Sun, 14 Sep 2014 10:38:11 -0400 + diff --git a/changelog b/changelog new file mode 100644 index 0000000..3a32d1d --- /dev/null +++ b/changelog @@ -0,0 +1,5 @@ +spd-perl (0.2-1) unstable; urgency=low + + * Initial release (Closes: #nnnn) + + -- unknown Sun, 14 Sep 2014 10:38:11 -0400 diff --git a/compat b/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/compat @@ -0,0 +1 @@ +9 diff --git a/control b/control new file mode 100644 index 0000000..a1c800c --- /dev/null +++ b/control @@ -0,0 +1,17 @@ +Source: spd-perl +Section: main +Priority: optional +Maintainer: Lisa Maginnis +Build-Depends: debhelper (>= 8.0.0), autotools-dev +Standards-Version: 3.9.4 +Homepage: http://spd.sourceforge.net/ +#Vcs-Git: git://git.debian.org/collab-maint/spd.git +#Vcs-Browser: http://git.debian.org/?p=collab-maint/spd.git;a=summary + +Package: spd-perl +Architecture: i386 amd64 +Depends: perl, libgnupg-interface-perl, libdigest-md5-file-perl, libswitch-perl, ${shlibs:Depends}, ${misc:Depends} +Description: A multiuser password managing software based on GnuPG. + The "Simple Password Displayer" is a multiuser password managing software + based on GnuPG, so every user has his own password to decrypt/sign the + container. diff --git a/copyright b/copyright new file mode 100644 index 0000000..da3434e --- /dev/null +++ b/copyright @@ -0,0 +1,49 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: spd-perl +Source: + +Files: * +Copyright: 2008 treibholz + 2008 Z3po + 2008 badticket +License: GPL-2 + This package 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; version 2 of the License. + . + This package 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 + 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, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +# If you want to use GPL v2 or later for the /debian/* files use +# the following clauses, or change it to suit. Delete these two lines +Files: debian/* +Copyright: 2014 Lisa Maginnis +License: GPL-2 + This package 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 of the License, or + (at your option) any later version. + . + This package 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 + 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, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +# Please also look if there are files or directories which have a +# different copyright/license attached and list them here. +# Please avoid to pick license terms that are more restrictive than the +# packaged work, as it may make Debian's contributions unacceptable upstream. diff --git a/docs b/docs new file mode 100644 index 0000000..50bd824 --- /dev/null +++ b/docs @@ -0,0 +1,2 @@ +NEWS +README diff --git a/files b/files new file mode 100644 index 0000000..247d278 --- /dev/null +++ b/files @@ -0,0 +1 @@ +spd-perl_0.2-1_i386.deb main optional diff --git a/rules b/rules new file mode 100755 index 0000000..8ef59d7 --- /dev/null +++ b/rules @@ -0,0 +1,14 @@ +#!/usr/bin/make -f +# -*- makefile -*- + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +%: + dh $@ --with autotools-dev +override_dh_auto_clean: + $(MAKE) clean + rm Makefile +override_dh_auto_install: + sed 's_local/__g' -i Makefile + $(MAKE) prefix=debian/spd-perl/usr perllibdir=debian/spd-perl/usr/lib/perl install diff --git a/source/format b/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/spd-perl.debhelper.log b/spd-perl.debhelper.log new file mode 100644 index 0000000..aae4cac --- /dev/null +++ b/spd-perl.debhelper.log @@ -0,0 +1,22 @@ +dh_autotools-dev_updateconfig +dh_auto_configure +dh_auto_build +dh_auto_test +dh_prep +dh_installdirs +dh_auto_install +dh_installdocs +dh_installchangelogs +dh_installman +dh_perl +dh_link +dh_compress +dh_fixperms +dh_strip +dh_makeshlibs +dh_shlibdeps +dh_installdeb +dh_gencontrol +dh_md5sums +dh_builddeb +dh_builddeb diff --git a/spd-perl.dirs b/spd-perl.dirs new file mode 100644 index 0000000..681cc0f --- /dev/null +++ b/spd-perl.dirs @@ -0,0 +1,4 @@ +usr/bin +usr/lib/perl +usr/share/man/man1 +usr/share/man/man5 \ No newline at end of file diff --git a/spd-perl.substvars b/spd-perl.substvars new file mode 100644 index 0000000..bcb0957 --- /dev/null +++ b/spd-perl.substvars @@ -0,0 +1,2 @@ +perl:Depends=perl +misc:Depends= diff --git a/spd-perl/DEBIAN/control b/spd-perl/DEBIAN/control new file mode 100644 index 0000000..4ace581 --- /dev/null +++ b/spd-perl/DEBIAN/control @@ -0,0 +1,13 @@ +Package: spd-perl +Version: 0.2-1 +Architecture: i386 +Maintainer: Lisa Maginnis +Installed-Size: 154 +Depends: perl, libgnupg-interface-perl, libdigest-md5-file-perl, libswitch-perl +Section: main +Priority: optional +Homepage: http://spd.sourceforge.net/ +Description: A multiuser password managing software based on GnuPG. + The "Simple Password Displayer" is a multiuser password managing software + based on GnuPG, so every user has his own password to decrypt/sign the + container. diff --git a/spd-perl/DEBIAN/md5sums b/spd-perl/DEBIAN/md5sums new file mode 100644 index 0000000..ba97612 --- /dev/null +++ b/spd-perl/DEBIAN/md5sums @@ -0,0 +1,17 @@ +527b49d511a2575eabb5e0c4433d3d12 usr/bin/spd +3b894c80c9f48767ce6e0751455c6753 usr/lib/perl/5.18.2/SPD/deleting_column.pm +0b70a199a858b11a0d7a3874f63f1f08 usr/lib/perl/5.18.2/SPD/exporting.pm +2f694d39f6175a0e27854ed5fc44543b usr/lib/perl/5.18.2/SPD/importing.pm +efadd8d2cffc8fb9ec6cb0ad367b8126 usr/lib/perl/5.18.2/SPD/unix_adding.pm +2cb2893fe6654bb5bb19e912907bcabb usr/lib/perl/5.18.2/SPD/unix_create_config.pm +3f2d1d7662b3bd421bd290199fe07f3b usr/lib/perl/5.18.2/SPD/unix_editing.pm +41524ed2253d6ad4e73ab1aa31efc2f9 usr/lib/perl/5.18.2/SPD/unix_print_results.pm +b60ba89d989ded21a16499a14b3cdffc usr/share/doc/spd-perl/NEWS.gz +84363b8e1cbab237e4b2de8b6b1ff70b usr/share/doc/spd-perl/README +bd75b9c232cf44b08476b2d03bd23e4b usr/share/doc/spd-perl/README.Debian +dc02b8b63dabb488d25fc5cd3b02e531 usr/share/doc/spd-perl/changelog.Debian.gz +bf18a806042fb0c78507f9fd06e8846b usr/share/doc/spd-perl/copyright +6c48c0084bb1cc5a130c95e290453223 usr/share/man/de/man1/spd.1.gz +7082c31f3df1314fbdc87f2ccc95002b usr/share/man/de/man5/spd.conf.5.gz +7fe0b0f4790bb69e1783f3e575d20bd1 usr/share/man/man1/spd.1.gz +404689421d678d3944bbde054873e655 usr/share/man/man5/spd.conf.5.gz diff --git a/spd-perl/usr/bin/spd b/spd-perl/usr/bin/spd new file mode 100755 index 0000000..03385ca --- /dev/null +++ b/spd-perl/usr/bin/spd @@ -0,0 +1,718 @@ +#!/usr/bin/perl +# +# (c) 2008 spd-developer-team +# treibholz +# Z3po +# badticket +# GPL + +use strict; # strict handling +use warnings; # show warnings +use Getopt::Long; # used to make -parameter possible + Getopt::Long::Configure ("bundling"); # you can combine parameters with it. -avx = -a -v -x +use GnuPG::Interface; # GPG Interface for perl +use IO::Handle; # module to open filehandles +use IO::File; # needed to open files directly +use Switch; # module to handle switches +use File::Temp qw/ tempfile /; # needed to create secure temporary files +use File::Copy; # needed to copy files +use Term::ANSIColor qw(:constants); # make color possible + $Term::ANSIColor::AUTORESET = 1; # autoreset colorscheme after each \n +use Digest::MD5::File qw(file_md5_hex); # +#use open ':utf8'; # all input and output strings shall be utf8 strings +#can not be used because of destroying the "--edit" procedure. umlauts are displayed mutated + +my $GLOBALSETTINGS = {}; +my $GLOBALPARAMETERS = {}; +$main::GLOBALSETTINGS->{HOME} = $ENV{'HOME'}; +$main::GLOBALSETTINGS->{SPD_DIR} = "$main::GLOBALSETTINGS->{HOME}/.spd"; +$main::GLOBALSETTINGS->{EDITOR} = "vi"; +$main::GLOBALSETTINGS->{VERSION} = "0.2-UNKNOWN"; +$main::GLOBALSETTINGS->{SYSTEM_CONFIG} = "/etc/spd/spd.conf"; + +# Function to check if all needed variables are set and make them global accessible +# There are no parameters needed calling this function. It does not return anything. + sub check_config + { + my $passfile_not_forced = shift; + my $config; + + # check if configfile is present + if ( !$main::GLOBALSETTINGS->{CONFIG_FILE} ){ # if configfile did not get set with --config + $main::GLOBALSETTINGS->{CONFIG_FILE} = "$main::GLOBALSETTINGS->{SPD_DIR}/spd.conf"; # set default configfile + if ( -e $main::GLOBALSETTINGS->{CONFIG_FILE} ){ # is configfile there? + $config=parse_config($main::GLOBALSETTINGS->{CONFIG_FILE}); # get the config parameters + } + elsif ( -e $main::GLOBALSETTINGS->{SYSTEM_CONFIG} ){ # check for system-wide configfile + $config=parse_config($main::GLOBALSETTINGS->{SYSTEM_CONFIG}); # get the config parameters + } + else { + require SPD::unix_create_config; + print "CONFIG FILE NOT FOUND!\n"; + print "Do you want to create one with the wizard (w) or generate a default one (d) ?"; + my $answer = ; + chomp($answer); + + if ( $answer eq "w" ) { + config_wizard(); + } + elsif ( $answer eq "d" ) { + print "GENERATING A SAMPLE TO $main::GLOBALSETTINGS->{CONFIG_FILE}\n"; + default_config(); + } + else { + die "Did nothing. You cannot do anything without a working configfile.\n"; + } + exit 0; + } + } + else { + if ( !-f $main::GLOBALSETTINGS->{CONFIG_FILE} ){ # checks wether configfile is a file + die "FILE \"$main::GLOBALSETTINGS->{CONFIG_FILE}\" NOT FOUND!\n" + } + else { + $config=parse_config($main::GLOBALSETTINGS->{CONFIG_FILE}); # get the config parameters + } + } + + # is the EDITOR-variable defined? if not let it be "vi" + if ( $config->{EDITOR} ){ + $main::GLOBALSETTINGS->{EDITOR} = $config->{EDITOR}; + } + + # is a shared PASSFILE defined? and readable? + if ( $config->{SHARED_PASSFILE} && !$main::GLOBALPARAMETERS->{LOCAL} ){ + if ( !-r $config->{SHARED_PASSFILE} && !$main::GLOBALPARAMETERS->{CREATE} ) { + die "PASSFILE $config->{SHARED_PASSFILE} NOT FOUND OR NOT READABLE!\nForgot --create?\nForgot --local?\n"; + } + else { + $main::GLOBALSETTINGS->{SHARED_PASSFILE} = $config->{SHARED_PASSFILE}; + } + } + + # is PASSFILE defined? and readable? + if ( !$main::GLOBALSETTINGS->{PASSFILE} || $passfile_not_forced ){ + if ( $config->{PASSFILE} ){ + $main::GLOBALSETTINGS->{PASSFILE} = $config->{PASSFILE}; + $passfile_not_forced = "1"; + if ( !-r $main::GLOBALSETTINGS->{PASSFILE} && !$main::GLOBALPARAMETERS->{CREATE} ) { + die "PASSFILE $main::GLOBALSETTINGS->{PASSFILE} NOT FOUND OR NOT READABLE!\nForgot --create?\n"; + } + } + else { + die "PASSFILE NOT DEFINED!\n"; + } + } + else { + if ( !-r $main::GLOBALSETTINGS->{PASSFILE} && !$main::GLOBALPARAMETERS->{CREATE} ) { + die "PASSFILE $main::GLOBALSETTINGS->{PASSFILE} NOT FOUND OR NOT READABLE!\nForgot --create?\n" + } + } + + # is YOUR_ID defined? + if ( $config->{YOUR_ID} ) { + $main::GLOBALSETTINGS->{YOUR_NAME} = $config->{YOUR_ID}; + } + else { + die "YOUR_ID NOT SET! CHECK YOUR CONFIGFILE\n"; + } + if ( $config->{$main::GLOBALSETTINGS->{YOUR_NAME}} ) { + $main::GLOBALSETTINGS->{YOUR_ID} = $config->{$main::GLOBALSETTINGS->{YOUR_NAME}}; + } + else { + die "$main::GLOBALSETTINGS->{YOUR_NAME} NOT DEFINED!\n"; + } + + # get the gpg-key of TRUSTED_ID + if ( $config->{TRUSTED_IDS} ){ + @{$main::GLOBALSETTINGS->{IDS}} = {}; + my @name = split(/\s+/, $config->{TRUSTED_IDS}); + my $elements = @name; + for ( my $i=0; $i<$elements; $i++) { + if ( $config->{$name[$i]} ) { + ${$main::GLOBALSETTINGS->{IDS}}[$i] = "$config->{$name[$i]}"; + } + else { + die "$name[$i] NOT DEFINED! CHECK YOUR CONFIGFILE"; + } + } + } + + # get the lines which should be colored + if ( $config->{RED} ){ + $main::GLOBALSETTINGS->{RED} = $config->{RED}; + } + if ( $config->{YELLOW} ){ + $main::GLOBALSETTINGS->{YELLOW} = $config->{YELLOW}; + } + if ( $config->{BLUE} ){ + $main::GLOBALSETTINGS->{BLUE} = $config->{BLUE}; + } + if ( $config->{GREEN} ){ + $main::GLOBALSETTINGS->{GREEN} = $config->{GREEN}; + } + if ($config->{PASSWORD} ){ + $main::GLOBALSETTINGS->{PASSWORDLINE} = $config->{PASSWORD}; + } + + # is an additional configfile defined? + if ( $config->{INCLUDE} ){ + $main::GLOBALSETTINGS->{CONFIG_FILE} = $config->{INCLUDE}; + check_config($passfile_not_forced); + } + } + +# decrypt the passfile +# given parameter is location of the passfile. +# it returns the decrypted passfile array + sub decrypt_passfile + { + my $file = shift; + my $gnupg = GnuPG::Interface->new(); # load object +# $gnupg->options->hash_init(armor => 1); # set armor enabled (not needed here) + my $output = IO::Handle->new(); # output Handle + my $infile = IO::File->new( "<$file" ); # open $PASSFILE for reading + my $handles = GnuPG::Handles->new( stdin => $infile, + stdout => $output, + stderr => "/dev/null"); + $handles->options( 'stdin' )->{direct} = 1; + $gnupg->passphrase( my $passphrase ); # Load the passphrase from STDIN + my $pid = $gnupg->decrypt( handles => $handles ); # start the decryption + close $infile; # close $cipher_file + my @decrypted = <$output>; # insert output in array "@result" + close $output; # close $output + waitpid $pid, 0; # clean up the finished GnuPG process + return @decrypted; # return the decrypted passfile + + } + +# encrypt given array to $OUTFILE and move it to $PASSFILE +# parameter give is the location where the encrypted file should be saved (first) and the array to encrpyt (second) +# nothing is returned + sub encrypt_array + { + my ($output_file_fh, $output_file) = tempfile(); + my $outfile = shift; + my @input_array = @_; + + my $gnupg = GnuPG::Interface->new(); # load object + + my $input = IO::Handle->new(); + + # We'll let the standard error of GnuPG pass through + # to our own standard error, by not creating + # a stderr-part of the $handles object. + + my $handles = GnuPG::Handles->new( stdin => $input, + stdout => $output_file_fh); + + $handles->options( 'stdout' )->{direct} = 1; # think this is needed when using files + + $gnupg->options->armor( 1 ); + $gnupg->options->default_key ( $main::GLOBALSETTINGS->{YOUR_ID} ); # set default id here (if you have multiple ids you need that) + $gnupg->options->push_recipients ( $main::GLOBALSETTINGS->{YOUR_ID} ); # set own-id to encrypt file + + if ( $main::GLOBALSETTINGS->{IDS} ) { + foreach my $id ( @{$main::GLOBALSETTINGS->{IDS}} ) { + $gnupg->options->push_recipients ( $id ); # set all the other ids + } + } + + # this sets up the communication + # Note that the recipients were specified earlier + # in the 'options' data member of the $gnupg object. + my $pid = $gnupg->sign_and_encrypt( handles => $handles ); + + print $input @input_array; + + # this closes the communication channel, + # indicating we are done + close $input; + close $output_file_fh; + + waitpid $pid, 0; # clean up the finished GnuPG process + + if ( $? == 0 ) { + move($output_file, $outfile) || die "WARNING!! File $output_file cannot be moved to $outfile.\n$outfile not writeable?\n"; + print "seems to me that everything worked fine. Passfile encrypted.\n"; + } + else { + die "something went wrong, encryption stopped. hope you did not lose any changes?!?"; + } + } + +# encrypt given File to $OUTFILE and move it to $PASSFILE +# there are two parameters given. The file where the plaintext is in (first) and the location where the encrypted file should be saved (second) +# nothing is returned + sub encrypt_file + { + my ($output_file_fh, $output_file) = tempfile(); + my $input_file = shift; + my $outfile = shift; + my $gnupg = GnuPG::Interface->new(); # load object + + # We'll let the standard error of GnuPG pass through + # to our own standard error, by not creating + # a stderr-part of the $handles object. + my $infile = IO::File->new( "$input_file" ); + + my $handles = GnuPG::Handles->new( stdin => $infile, + stdout => $output_file_fh); + + $handles->options( 'stdin' )->{direct} = 1; # set option to directly use the filehandles + $handles->options( 'stdout' )->{direct} = 1; # think this is needed when using files + + $gnupg->options->armor( 1 ); + $gnupg->options->default_key ( $main::GLOBALSETTINGS->{YOUR_ID} ); # set default id here (if you have multiple ids you need that) + $gnupg->options->push_recipients ( $main::GLOBALSETTINGS->{YOUR_ID} ); # set own-id to encrypt file + + if ( $main::GLOBALSETTINGS->{IDS} ) { + foreach my $id ( @{$main::GLOBALSETTINGS->{IDS}} ) { + $gnupg->options->push_recipients ( $id ); # set all the other ids + } + } + + # this sets up the communication + # Note that the recipients were specified earlier + # in the 'options' data member of the $gnupg object. + my $pid = $gnupg->sign_and_encrypt( handles => $handles ); + + # this closes the communication channel, + # indicating we are done + close $infile; + close $output_file_fh; + + waitpid $pid, 0; # clean up the finished GnuPG process + + if ( $? == 0 ) { + move($output_file, $outfile) || die "WARNING!! File $output_file cannot be moved to $outfile.\n$outfile not writeable?\n"; + print "seems to me that everything worked fine. Passfile encrypted.\n"; + } + else { + die "something went wrong, encryption stopped. hope you did not lose any changes?!?"; + } + + + } + +# check if the edited file is ok +# parameter is the location of the passfile +# it returns just successfull (0) or error (1) + sub check_quantity + { + my $file = shift; + open(my $filehandle,'<'.$file) || die "Cannot open $file: $! that shouldn't happen\n"; + my @checkarray = <$filehandle>; + close($filehandle) || die "Cannot close $file ?!?!? WTF that shouldn happen\n"; + my $counter = 1; + my $max_desclength = 0; + + if ( @checkarray ) { # check if something IS in $file + my @description = split(/\t/,$checkarray[0]); #save Description + shift ( @checkarray ); # delete description from array + + my $quantity_desc = @description; # save Quantity of Array Description + + foreach my $line (@checkarray){ + $counter++; + my @result = split(/\t/,$line); + my $quantity_result = @result; + if ( $quantity_desc != $quantity_result ) { # do the check + print "ERROR - Quantity of description does not match quantity of results in line $counter\nof your datafile, there are $quantity_result instead of $quantity_desc items, which results in an ERROR\n"; + return 1; + } + } + } + else { + print "$file has been empty. Return successfull state to go on.\n"; + } + return 0; + } + +# sub to compare 2 files. +# there are two parameters given containing the location of the files +# it does not return anything but handle overwriting files internally + sub compare_passfiles + { + my $first_passfile = shift; + my $second_passfile = shift; + my $md5sum_first_passfile = file_md5_hex($first_passfile); + my $md5sum_second_passfile = file_md5_hex($second_passfile); + + if ( $md5sum_first_passfile ne $md5sum_second_passfile ) { + print "size of $first_passfile does not match $second_passfile what would you like to do?\n"; + print "a) overwrite $second_passfile with $first_passfile\n"; + print "b) overwrite $first_passfile with $second_passfile\n"; + print "c) do nothing at all\n"; + my $selection = ; + chomp($selection); + + switch ($selection) { + + case "a" { + copy($second_passfile, "$second_passfile.bak") || print "Could not make a copy of $second_passfile!\n"; + copy($first_passfile, $second_passfile) || die "Could not copy $second_passfile to $first_passfile. FAILED!\n$first_passfile not writeable?\n"; + print "PASSFILE copied.\nBackup is $second_passfile.bak\nPress Enter to continue..."; + my $buffer = ; + } + case "b" { + copy($first_passfile, "$first_passfile.bak") || print "Could not backup $first_passfile\n"; + copy($second_passfile, $first_passfile) || die "Could not copy $first_passfile to $second_passfile, FAILED!\n$second_passfile not writeable?\n"; + print "PASSFILE copied.\nBackup is $first_passfile.bak\nPress Enter to continue..."; + my $buffer = ; + } + case "c" { print "Did nothing.\n" } + else { print "OPTION unknown. Did nothing.\n" } + } + } + } + +# function to get max length of string +# parameter given is a array +# nothing is returned + sub get_max_length { + my $length = shift; + my @string = @_; + # get max length of "DESCRIPTION" + foreach my $part_of_string ( @string ) { + my $length_string = length $part_of_string; + if ( $length < $length_string ) { + $length = $length_string; + } + } + return $length; + } + +# function to join a given array to file +# parameters given are the location of the passfile (first) and the array i want to join in (second) + sub join_array_to_file + { + my $file = shift; + my @first_array = @_; + my @second_array = decrypt_passfile($file); + my @diff_array; + my $diff_counter = 0; + my $is_equal = 0; + + my $quantity_first_array = @first_array; + my $quantity_second_array = @second_array; + + for ( my $i = 0; $i < $quantity_first_array; $i++ ) { + for ( my $x = 0; $x < $quantity_second_array; $x++ ) { + if ( $first_array[$i] eq $second_array[$x] ) { + $is_equal = 1; + last; + } + else { + $diff_array[$diff_counter] = $first_array[$i]; + } + } + if ( $is_equal ) { + $is_equal = 0; + } + else { + $diff_counter++; + } + } + my @result_array = (@second_array,@diff_array); + return @result_array; + } + +# function to make string or array equal to max length +# parameters given are the length all columns should have (first) and the array itself (second) +# returned is the array, length adjusted + sub make_strings_equal { + my $length = shift; + my @string = @_; + my $quantity_string = @string; + # make them all to one length + for ( my $i = 0; $i < $quantity_string; $i++ ) { + my $length_string = length $string[$i]; + my $missing = $length - $length_string; + for ( my $x = 0; $x < $missing; $x++ ) { + $string[$i] = $string[$i] . " "; + } + } + return @string; + } + +# does string contain any of string? +# parameter given is the string i'm searching in (first) and the searchword (second) +# returned is just true or false + sub string_contains_string { + my $string = shift; + my $string2 = shift; + + if ( !$string2 ) { return 1} + elsif ($string =~ /$string2/i) {return 1;} + else { return 0; } + } + +# does string contain any of array? +# parameters given are the string to search in (first) and the searchwords (second) +# returned is just true or false + sub string_equals_array + { + my $string = shift; + my @array = ""; + if ( $_[0] ) { + @array = split(/\s+/, $_[0]); + } + + if ( $string ) { + $string =~ s/\s+$//g; # remove whitespaces out of string + + if ( $array[0] ne "" ) { + foreach my $array_element (@array) { + $array_element =~ s/::/ /g; + if ($string =~ /^$array_element+$/) {return 1;}} + } + return 0; + } + else { + return 0; + } + } + +# Procedure to check the configuration file and load the settings +# got this configuration parser from http://www.patshaping.de/hilfen_ta/codeschnipsel/perl-configparser.htm +# it needs the configfile as parameter and returns all the values + sub parse_config($) + { + my $file = shift; + local *CF; + + open(CF,'<'.$file) || die "Open $file: $!\n"; + read(CF, my $data, -s $file); + close(CF) || die "could not close $file. that shouldn't happen\n"; + + my @lines = split(/\015\012|\012|\015/,$data); + my $config = {}; + my $count = 0; + + foreach my $line(@lines) + { + $count++; + + next if($line =~ /^\s*#/); + next if($line !~ /^\s*\S+\s*=.*$/); + + my ($key,$value) = split(/=/,$line,2); + + # Remove whitespaces at the beginning and at the end + + $key =~ s/^\s+//g; + $key =~ s/\s+$//g; + $value =~ s/^\s+//g; + $value =~ s/\s+$//g; + + die "Configuration option '$key' defined twice in line $count of configuration file '$file'" if($config->{$key}); + + $config->{$key} = $value; + } + + return $config; + } + +# dummy function to handle shared passfile or not before creating passfile. +# this function does not get any parameters nor returns any. + sub creating_passfile + { + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL} ) { + create_passfile($main::GLOBALSETTINGS->{PASSFILE}); # if wether shared passfile is set or --local is given + } + else { + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock" && !$main::GLOBALPARAMETERS->{FORCE} ) { # if lockfile is already set return username + open (my $lockfile,"<$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock") || die "COULD NOT OPEN LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock: $!. THAT SHOULDN'T HAPPEN!"; + my $current_user = <$lockfile>; + close($lockfile) || die "COULD NOT CLOSE LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock: $!. THAT SHOULDN'T HAPPEN!"; + print "You cannot overwrite $main::GLOBALSETTINGS->{SHARED_PASSFILE} as it is currently processed by $current_user\ntry --force if you really want to ignore it (changes will be lost)\n"; + } + else { + if ( $main::GLOBALPARAMETERS->{FORCE} ) { # overwrite lockfile if set + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock" ) { + unlink("$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock"); + } + } + open (my $lockfile,">$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock") || die "COULD NOT OPEN LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock for writing: $!.\nDoing this would be insecure\n"; + print $lockfile "$main::GLOBALSETTINGS->{YOUR_NAME} (creating passfile)"; + close($lockfile) || die "COULD NOT CLOSE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock after writing: $!.\n that REALLY shouldn't happen!\n"; + create_passfile($main::GLOBALSETTINGS->{SHARED_PASSFILE}); # added lockfile. Now do real adding. + unlink("$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock"); + } + } + } + + +# Procedure to create a new passfile. +# it gets the passfile-location as parameter. +# it returns nothing. + sub create_passfile + { + my $file = shift; + my @PASSFILE; + + if ( -f $file ) { + print "PASSFILE $file exists, do you want to override(y/n)?"; + my $answer = ; + chomp($answer); + if ( $answer eq "n" ) { + return 0; + } + } + open(my $FH,'>'.$file) || die "Could not Open $file: $!\n"; + + print "Which Name should the first column have?"; + my $answer = ; + chomp($answer); + $PASSFILE[0] = $answer; + $answer = ""; + + while ( $answer ne "n" ) { + print "Do you want to add another column?(y/n)"; + $answer = ; + chomp($answer); + if ( $answer eq "y" ) { + print "what name should the column have?:"; + $answer = ; + chomp($answer); + $PASSFILE[0] = $PASSFILE[0] . "\t" . $answer; + $answer = ""; + } + } + $PASSFILE[0] = $PASSFILE[0] . "\n"; + + print "Do you want to create some entries right now?(y/n)"; + $answer = ; + chomp($answer); + if ( $answer eq "y" ) { + require SPD::unix_adding; + add_line($file, @PASSFILE); + } + } + +# print helptext +# no parameters needed nothing returned + + sub show_help + { + print "SPD - Simple Password Displayer - Version $main::GLOBALSETTINGS->{VERSION}\n\n"; + print "Syntax: spd [options]|\n\n"; + print "main options:\n"; + print " --help | -h : display this wonderful help\n"; + print " --version | -v : shows version information\n"; + print " --import | -i : import a cleartext-file\n"; + print " --export : to export as a cleartext-file\n"; + print " --config | -c : use configfile instead of the standard ones\n"; + print " --passfile| -p : use passfile instead of the one set in spd.conf\n"; + print " --local | -l : use local passfile instead of the shared one\n"; + print " --force | -f : forcing some operations\n"; + print " --wide | -w : give output in wide Format\n"; + print " --create : create a passfile using the wizard\n\n"; + print "passfile options:\n"; + print " --delete-column : delete a column by number or word of the description\n"; + print " Note: The ID Column cannot be deleted.\n"; + print " --edit | -e : edit the password-file with your favourite editor\n"; + print " --add | -a : interactive add a line\n\n"; + print "import/export options:\n"; + print " --field-delimiter : char which is used to delimiter the fields\n"; + print " --column-delimiter : char which is used to delimiter the columns\n\n"; + print "other options:\n"; + print " --config-wizard : create a config using the wizard\n"; + print " Note: will delete existing config if exist\n\n"; + print "With no parameters it will print out everything!\n"; + exit 0; + } + +# Main Methods + +GetOptions ('help|h' => \my $help, + 'version|v' => \my $version, + 'import|i=s' => \$main::GLOBALPARAMETERS->{IMPORT}, + 'export=s' => \$main::GLOBALPARAMETERS->{EXPORT}, + 'config|c=s' => \my $conffile, + 'passfile|p=s' => \my $passfile, + 'local|l' => \$main::GLOBALPARAMETERS->{LOCAL}, + 'force|f' => \$main::GLOBALPARAMETERS->{FORCE}, + 'wide|w' => \$main::GLOBALPARAMETERS->{WIDE}, + 'create' => \$main::GLOBALPARAMETERS->{CREATE}, + 'delete-column=s' => \my $delete_column, + 'edit|e' => \my $edit, + 'add|a' => \my $add, +# 'checksign|cs' => \my $checksign, + 'field-delimiter=s' => \$main::GLOBALPARAMETERS->{FIELD_DELIMITER}, + 'column-delimiter=s' => \$main::GLOBALPARAMETERS->{COLUMN_DELIMITER}, + 'config-wizard' => \my $config_wizard); + + if ( $help ){ + show_help; + } + + if ( $version ){ + print "SPD - Simple Password Displayer - Version $main::GLOBALSETTINGS->{VERSION}\n\n"; + exit 0; + } + + if ( $conffile ){ + $main::GLOBALSETTINGS->{CONFIG_FILE} = $conffile + } + + if ( $config_wizard ){ + require SPD::unix_create_config; + config_wizard(); + exit 0; + } + + if ( $passfile ){ + $main::GLOBALSETTINGS->{PASSFILE} = $passfile + } + + # we need to check the config before doing any of the following + check_config(); + +# if ( $checksign ){ +# check_sign; +# } + + if ( $main::GLOBALPARAMETERS->{CREATE} ) { + create_passfile($main::GLOBALSETTINGS->{PASSFILE}); + exit 0; + } + + elsif ( $delete_column ){ + require SPD::deleting_column; + deleting_column($delete_column); + exit 0; + } + + elsif ( $add ){ + require SPD::unix_adding; + adding(); + exit 0; + } + + elsif ( $edit ){ + require SPD::unix_editing; + editing(); + exit 0; + } + + elsif ( $main::GLOBALPARAMETERS->{IMPORT} ){ + require SPD::importing; + importing(); + exit 0; + } + + elsif ( $main::GLOBALPARAMETERS->{EXPORT} ){ + require SPD::exporting; + exporting(); + exit 0; + } + + else { + require SPD::unix_print_results; + searching(); + exit 0; + } + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/deleting_column.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/deleting_column.pm new file mode 100644 index 0000000..14cdf41 --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/deleting_column.pm @@ -0,0 +1,164 @@ + sub deleting_column + { + my $delete_column = shift; + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL} ) { + delete_column($main::GLOBALSETTINGS->{PASSFILE}, $delete_column); + } + else { + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}" ) { + delete_column($main::GLOBALSETTINGS->{SHARED_PASSFILE}, $delete_column); + } + else { + die "Shared Passfile $main::GLOBALSETTINGS->{SHARED_PASSFILE} is defined but not there.\nForgot --local?\n"; + } + } + + } + + # delete a whole column + # parameter given is the location of the passfile (first) and the column to search or delete (second) + # nothing is returned + sub delete_column + { + my ($fh, $MKTEMP) = tempfile( UNLINK => 1 ); + close ($fh) || die "Could not close temporary filehandle for $MKTEMP. that shouldn't happen\n"; + my $file = shift; + my $searchcolumn = shift; + my $notfound = 0; + + my @plainpassfile = decrypt_passfile($file); # get decrypted passarray + if ( !@plainpassfile ) { # did get empty array anyhow + die "$file has no DATA?\nTyped Passphrase three times wrong?\n"; + } + + my @description = split(/\t/,$plainpassfile[0]); #save Description + + my $quantity_plainpassfile = @plainpassfile; + + if ($searchcolumn =~ /^[0-9]*$/) { + print "You want to delete column number $searchcolumn?(y/n)"; + my $answer = ; + chomp($answer); + + if ( $answer eq "y" ) { + $searchcolumn = ($searchcolumn-1); + for ( my $i = 0; $i < $quantity_plainpassfile; $i++ ){ + my $line = $plainpassfile[$i]; + my @columns = split(/\t/,$line); + delete $columns[$searchcolumn-1]; + + $line = $columns[0]; + my $quantity_columns = @columns; + + if ( $quantity_columns <= 2 ) { + $notfound = 1; + } + else { + if ( $quantity_columns >= ($searchcolumn-1) ) { # searchcolumn-1 because if deleting last column + if ( $searchcolumn == 1 ) { + shift(@columns); + $line = $columns[0]; + $quantity_columns = @columns; + } + + for ( my $y = 1; $y < $quantity_columns-1; $y++ ){ + if ( $y != ($searchcolumn-1)) { + $line = $line . "\t" . $columns[$y]; + } + } + chomp($columns[$quantity_columns-1]); # you're wonderingy why i + $line = $line . "\t" . $columns[$quantity_columns-1] . "\n"; # first delete it and then append it? + $plainpassfile[$i] = $line; # what if deleting the last column? + } + else { + $notfound = 1; + } + } + } + + if ( !$notfound ) { + open(my $mktemp_fh,'>'.$MKTEMP) || die "Open $MKTEMP: $! that shouldn't happen\n"; + print $mktemp_fh @plainpassfile; + close($mktemp_fh) || die "cannot close $MKTEMP. WTF?? that shouldn't happen\n"; + encrypt_file($MKTEMP,$file); + } + + } + else { + print "ok, just did nothing...\n"; + } + } + else { + print "You want to delete the column containing $searchcolumn?(y/n)"; + my $answer = ; + my $counter = 0; + chomp($answer); + $notfound = 1; + + if ( $answer eq "y" ) { + foreach my $desccolumn ( @description ) { + $counter++; + if ( grep (/$searchcolumn/i, $desccolumn) ) { # search for matching patterns + $notfound = 0; + print "match in column " . ($counter+1) . "\n"; + print "Are you sure to delete column nr. " . ($counter+1) . "?(y/n)"; + $answer = ; + chomp($answer); + if ( $answer eq "y" ) { + + for ( my $i = 0; $i < $quantity_plainpassfile; $i++ ){ + my $line = $plainpassfile[$i]; + my @columns = split(/\t/,$line); + delete $columns[$counter-1]; + my $quantity_columns = @columns; + + if ( $quantity_columns <= 2 ) { + $notfound = 1; + } + else { + if ( $quantity_columns >= ($counter-1) ) { # counter-1 because if deleting last column + if ( $counter == 1 ) { + shift(@columns); + $line = $columns[0]; + $quantity_columns = @columns; + } + $line = $columns[0]; + for ( my $y = 1; $y < $quantity_columns-1; $y++ ){ + if ( $y != ($counter-1) ) { + $line = $line . "\t" . $columns[$y]; + } + } + chomp($columns[$quantity_columns-1]); + $line = $line . "\t" . $columns[$quantity_columns-1] . "\n"; + $plainpassfile[$i] = $line; + } + else { + $notfound = 1; + } + } + } + + if ( !$notfound ) { + open(my $mktemp_fh,'>'.$MKTEMP) || die "Open $MKTEMP: $! that shouldn't happen\n"; + print $mktemp_fh @plainpassfile; + close($mktemp_fh) || die "cannot close $MKTEMP. WTF?? that shouldn't happen\n"; + encrypt_file($MKTEMP,$file); + } + } + else { + print "ok, just did nothing...\n"; + } + } + } + } + else { + print "ok, just did nothing...\n"; + } + } + if ( $notfound ) { + print "Sorry, could not delete column.\ncolumn not found or quantity das not match $file.\nIs your column-count > 4?\n"; + } + } + return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/exporting.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/exporting.pm new file mode 100644 index 0000000..0a632c4 --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/exporting.pm @@ -0,0 +1,57 @@ +# sub to do exporting the passfile plaintext +# there are no parameters given nor returned + sub exporting + { + my @plainpassfile; + my $outfile = $main::GLOBALPARAMETERS->{EXPORT}; + my $field_char = ""; + my $column_char = ""; + + # get the decrypted passfile + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL}) { + @plainpassfile = decrypt_passfile($main::GLOBALSETTINGS->{PASSFILE}); + if ( !@plainpassfile ) { + die "$main::GLOBALSETTINGS->{PASSFILE} has no DATA?\nTyped Passphrase three times wrong?\n"; + } + } + else { + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}" ) { + @plainpassfile = decrypt_passfile($main::GLOBALSETTINGS->{SHARED_PASSFILE}); + if ( !@plainpassfile ) { + die "$main::GLOBALSETTINGS->{SHARED_PASSFILE} has no DATA?\nTyped Passphrase three times wrong?\n"; + } + } + else { + die "Shared Passfile $main::GLOBALSETTINGS->{SHARED_PASSFILE} is defined but not there.\nForgot --local?\n"; + } + } + + if ( $main::GLOBALPARAMETERS->{FIELD_DELIMITER} ) { # set the field delimiters + $field_char = $main::GLOBALPARAMETERS->{FIELD_DELIMITER}; + } + if ( $main::GLOBALPARAMETERS->{COLUMN_DELIMITER} ) { + $column_char = $main::GLOBALPARAMETERS->{COLUMN_DELIMITER}; # set the column delimiters + } + + if ( $field_char || $column_char ) { # join the delimiters to array + my $quantity_passfile = @plainpassfile; + for ( my $i = 0; $i < $quantity_passfile; $i++ ) { + if ( $column_char ) { + $plainpassfile[$i] =~ s/\t/$field_char$column_char$field_char/g; + } + else { + $plainpassfile[$i] =~ s/\t/$field_char\t$field_char/g; + } + $plainpassfile[$i] = $field_char . $plainpassfile[$i]; + $plainpassfile[$i] =~ s/\n/$field_char\n/g; + } + } + + open(my $output,">$outfile") || die "COULD NOT WRITE TO $outfile: $!.\n"; + print $output @plainpassfile; # write the plainpassfile + close($output); + print "Seems that everything worked fine. Saved export to $outfile.\n"; + } + return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/importing.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/importing.pm new file mode 100644 index 0000000..2fa48f6 --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/importing.pm @@ -0,0 +1,81 @@ +# procedure managing the import +# there are no parameters given nor returned + sub importing + { + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL}) { # shared passfile or not? + if ( $main::GLOBALPARAMETERS->{FIELD_DELIMITER} || $main::GLOBALPARAMETERS->{COLUMN_DELIMITER} ) { # check wethere delimiters are set or not + import_file($main::GLOBALSETTINGS->{PASSFILE}); # if delimiters are set call import_file (to get the delimiters out of the file). + } + else { + encrypt_file($main::GLOBALPARAMETERS->{IMPORT},$main::GLOBALSETTINGS->{PASSFILE}); # if no delimiters are set we can just encrypt the file + } + } + else { # same thing with the shared_passfile + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}" ) { + if ( $main::GLOBALPARAMETERS->{FIELD_DELIMITER} || $main::GLOBALPARAMETERS->{COLUMN_DELIMITER} ) { + import_file($main::GLOBALSETTINGS->{SHARED_PASSFILE}); + compare_passfiles($main::GLOBALSETTINGS->{SHARED_PASSFILE}, $main::GLOBALSETTINGS->{PASSFILE}); + } + else { + encrypt_file($main::GLOBALPARAMETERS->{IMPORT},$main::GLOBALSETTINGS->{SHARED_PASSFILE}); + compare_passfiles($main::GLOBALSETTINGS->{SHARED_PASSFILE}, $main::GLOBALSETTINGS->{PASSFILE}); + } + } + else { + die "Shared Passfile $main::GLOBALSETTINGS->{SHARED_PASSFILE} is defined but not there.\nForgot --local?\n"; + } + } + } + + # procedure to import files with delimiter + sub import_file + { + my ($mktemp_fh, $MKTEMP) = tempfile( UNLINK => 1 ); + close ($mktemp_fh) || die "Could not close temporary filehandle for $MKTEMP. that shouldn't happen\n"; + my $passfile = shift; + my $field_char; + my $column_char; + + if ( $main::GLOBALPARAMETERS->{FIELD_DELIMITER} ) { + $field_char = $main::GLOBALPARAMETERS->{FIELD_DELIMITER}; + } + else { + $field_char = ""; + } + + if ( $main::GLOBALPARAMETERS->{COLUMN_DELIMITER} ) { + $column_char = $main::GLOBALPARAMETERS->{COLUMN_DELIMITER}; + } + else { + $column_char = ""; + } + + open (my $import_fh, "<$main::GLOBALPARAMETERS->{IMPORT}") || die "COULD NOT OPEN $main::GLOBALPARAMETERS->{IMPORT}.\n"; + my @imparray = <$import_fh>; + close ($import_fh) || die "COULD NOT CLOSE $import_fh. That's a real strange behaviour.\n"; + + my $array_length = @imparray; + $imparray[0] =~ s/^\xEF\xBB\xBF//; + + for ( my $i = 0; $i < $array_length; $i++ ) { + $imparray[$i] =~ s/\r//; + $imparray[$i] =~ s/\t/[TABSTOP]/g; + $imparray[$i] =~ s/$field_char$column_char$field_char/\t/g; + + if ((( $imparray[$i] =~ /"{1,}/ ) && ( $imparray[$i] !~ /"$/ )) || ( $imparray[$i] !~ /"/ )) { + $imparray[$i] =~ s/\n/\ [NEWLINE]\ /g; + } + + if ( $field_char ) { + $imparray[$i] =~ s/^$field_char//; + $imparray[$i] =~ s/$field_char$//; + } + } + open($mktemp_fh,'>'.$MKTEMP) || die "Open $MKTEMP: $! that shouldn't happen\n"; + print $mktemp_fh @imparray; + close($mktemp_fh) || die "Cannot close $MKTEMP ?!?!? WTF that shouldn happen\n"; + encrypt_file($MKTEMP,$passfile); + } + return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/unix_adding.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_adding.pm new file mode 100644 index 0000000..be98a99 --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_adding.pm @@ -0,0 +1,122 @@ +# This function is called if you want to add something with the --add option. +# No parameters are needed calling this. It will get Information out of global hashes. + sub adding + { + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL} ) { + add_line($main::GLOBALSETTINGS->{PASSFILE}); # if wether shared passfile is set or --local is given + } + else { + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}" ) { # create lockfile if using shared passfile + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock" && !$main::GLOBALPARAMETERS->{FORCE} ) { # if lockfile is already set return username + open (my $lockfile,"<$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock") || die "COULD NOT OPEN LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock: $!. THAT SHOULDN'T HAPPEN!"; + my $current_user = <$lockfile>; + close($lockfile) || die "COULD NOT CLOSE LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock: $!. THAT SHOULDN'T HAPPEN!"; + print "You cannot edit $main::GLOBALSETTINGS->{SHARED_PASSFILE} as it is currently processed by $current_user\ntry --force if you really want to edit it (changes maybe lost)\n"; + } + else { + if ( $main::GLOBALPARAMETERS->{FORCE} ) { # overwrite lockfile if set + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock" ) { + unlink("$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock"); + + } + } + open (my $lockfile,">$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock") || die "COULD NOT OPEN LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock for writing: $!.\nDoing this would be insecure\n"; + print $lockfile "$main::GLOBALSETTINGS->{YOUR_NAME} (adding entries)"; + close($lockfile) || die "COULD NOT CLOSE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock after writing: $!.\n that REALLY shouldn't happen!\n"; + add_line($main::GLOBALSETTINGS->{SHARED_PASSFILE}); # added lockfile. Now do real adding. + unlink("$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock"); + } + } + else { + die "Shared Passfile $main::GLOBALSETTINGS->{SHARED_PASSFILE} is defined but not there.\nForgot --local?\n"; # Shared Passfile is set but not available + } + } + } + +# add a line to @plainpassfile. +# given parameter is the location of the passfile. +# returns nothing + sub add_line + { + my $file = shift; + my @plainpassfile = @_; + if ( !@plainpassfile ) { + @plainpassfile = decrypt_passfile($file); + } + my $input; + my $line; + my $wanna_add = 1; + my $answer = ""; + + if ( !@plainpassfile ) { # anyhow a empty array is returned + die "$file has no DATA?\nTyped Passphrase three times wrong?\n"; + } + + my @description = split(/\t/,$plainpassfile[0]); #save description + chomp(@description); + + my $description_length = @description; # get length of description + + if ( $description_length < 3 ) { # need to implement this someday. Just commenting stuff this day (: + print "You cannot use this feature while your column count is less than 3\nNeed to implement this someday. If you really need this, please open a bugreport.\n"; + } + else { + print "Now you can add entries to your passfile\n"; + + my $md5sum_before_adding = file_md5_hex($file); # check md5sum of the passfile before changing the array + + while ( $wanna_add ) { + print "$description[0] :"; # first element needs to be added before because of joining them with \t + $input = ; + chomp($input); + $line = $input; + + for ( my $i = 1; $i < ($description_length-1); $i++ ){ + print "$description[$i] :"; # add all the other elements except the last one + $input = ; + chomp($input); + $line = $line . "\t" . $input; + } + $description[($description_length-1)] =~ s/\r//; # to get those windows linefeeds away + print "$description[($description_length-1)] :"; # this needs to get added after all others because of needing the \n + $line = $line . "\t" . ; + + push(@plainpassfile,$line); # add the line to the passfilearray + + print "do you want to add another entry?(y/n)"; + my $decision = ; + chomp($decision); + if ( $decision ne "y" ) { + $wanna_add = 0; + } + $decision = undef; + } + my $md5sum_after_adding = file_md5_hex($file); # check md5sum of the passfile after changing the array + if ( $md5sum_before_adding eq $md5sum_after_adding ) { # if they are not different we can encrypt the new array + encrypt_array($file, @plainpassfile); + } + else { + while ( $answer ne "y" && $answer ne "n" ) { # oh f*ck...somebody changed content while we were adding something + print "File has been changed while you were adding entries.\nMaybe someone used --force?\nDo you want to join your changes in?(y/n)\n"; + $answer = ; + chomp($answer); + if ( $answer eq "y" ) { + @plainpassfile = join_array_to_file($file, @plainpassfile); # try to join changes in and encrypt after + encrypt_array($file, @plainpassfile); + } + elsif ( $answer eq "n" ) { + print "Did nothing. Hope you did not lose any changes?!?\n"; + } + else { + print "not a valid answer, please try again.\n"; + $answer = ""; + } + } + } + } + + } + + return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/unix_create_config.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_create_config.pm new file mode 100644 index 0000000..9d597ad --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_create_config.pm @@ -0,0 +1,503 @@ +# function to receive the gpg_id from a keyserver +# given parameter can be a emailadress or gpg_id +# returned are status (set or not set) stdout [results] (set or not set) and the equal array + sub get_gpg_id + { + my @ids = @_; + my $gnupg = GnuPG::Interface->new(); + my ( $output, $status, $error ) = ( IO::Handle->new(), IO::Handle->new(), IO::Handle->new() ); + my $handles = GnuPG::Handles->new( stdout => $output, + stderr => "/dev/null", + status => $status); + + my $pid = $gnupg->recv_keys( handles => $handles, + command_args => [ @ids ] ); + + my @results = <$output>; + my @status = <$status>; + + close $output; + close $status; + + waitpid $pid, 0; + + if ( @status ) { + if ( @results ) { + return("1","1",@results); + } + else { + return("1","0",@status); + } + } + else { + return("0","0","The Key you entered was invalid or you do not have any keyrings configured.\nPlease try manually to receive this key."); + } + } + +# function to get the gpg_ids on your system or check if they are present +# parameter given is emailadress or gpg_id +# returned are the matches + sub show_gpg_id + { + my @ids = @_; + my $counter = 0; + my @results; + my $gnupg = GnuPG::Interface->new(); + my $output = IO::Handle->new(); + my $handles = GnuPG::Handles->new( stdout => $output, + stderr => "/dev/null"); + + my $pid = $gnupg->list_public_keys( handles => $handles, + command_args => [ @ids ] ); + + my @resultset = <$output>; + + waitpid $pid, 0; + close $output; + + $results[$counter] = ""; + foreach my $line (@resultset) { + if ( $line =~ m/^\n/ ) { + $counter++; + $results[$counter] = ""; + } + elsif ( $line =~ m/pub\s/ || $line =~ m/uid\s/ || $line =~ m/sub\s/ ) { + $results[$counter] =~ s/^\s//g; + $results[$counter] = $results[$counter] . $line; + } + } + return @results; + } + +# function to create a gpg_id on your system +# no parameters given +# returned is the gpg id + sub gen_gpg_id + { + my $result; + my $gnupg = GnuPG::Interface->new(); + my $output = IO::Handle->new(); + my $handles = GnuPG::Handles->new( stdout => $output, + stderr => "/dev/null"); + + my $pid = $gnupg->wrap_call ( commands => [ qw( --gen-key ) ], + handles => $handles); + + my @resultset = <$output>; + + waitpid $pid, 0; + close $output; + + foreach my $line (@resultset) { + if ( $line =~ m/pub\s/ ) { + $result = (split /\//,(split /\s/,$line, 0)[3])[1]; + } + } + return $result; + } + +# Generation wizzard for a config-file +# there ar no parameters needed and it does not return anything. + sub config_wizard + { + my $answers; + my $yes_no; + my $shared_users; + + if ( !$main::GLOBALSETTINGS->{CONFIG_FILE} ){ + $main::GLOBALSETTINGS->{CONFIG_FILE} = "$main::GLOBALSETTINGS->{SPD_DIR}/spd.conf"; + } + if ( $main::GLOBALSETTINGS->{CONFIG_FILE} eq "$main::GLOBALSETTINGS->{SPD_DIR}/spd.conf" ){ + if ( !-e "$main::GLOBALSETTINGS->{SPD_DIR}" ){ + mkdir("$main::GLOBALSETTINGS->{SPD_DIR}",0755) || die "cannot mkdir $main::GLOBALSETTINGS->{SPD_DIR}: $!\n"; + } + } + + open(my $configfile,">$main::GLOBALSETTINGS->{CONFIG_FILE}") || die "cannot create $main::GLOBALSETTINGS->{CONFIG_FILE}: $!\n"; + + # generating default header + print $configfile "## Configfile generated with configuration wizzard\n"; + print $configfile "#\n"; + print $configfile "## What is your NAME and GPG_ID?(needed):\n"; + print $configfile "#\n"; + + # getting your name and GPG_ID + print "What is your Name?(shouldn't have any spaces in it):"; + $answers = ; + chomp($answers); + print $configfile "YOUR_ID = " . $answers . "\n"; + print $configfile "#\n"; + print $configfile $answers; + print $configfile " = "; + + my @name; + my @id; + my @gpg_ids = show_gpg_id(); + my $entries = @gpg_ids; + $entries=($entries-1); + for ( my $i = 0; $i < ($entries); $i++ ) { + $name[$i] = (split /\s\s+/,(split /\n/, $gpg_ids[$i])[1])[1]; + $id[$i] = (split /\//,(split /\s/,(split /\n/, $gpg_ids[$i])[0])[3])[1]; + } + + if ( !@gpg_ids ) { + print "No gpg ids found. Do you want to create your own GPG ID now?"; + $yes_no = ; + chomp($yes_no); + + if ( $yes_no eq "y") { + $answers = gen_gpg_id(); + } + } + else { + print "Do you want to create your (o)wn gpg id now or (s)earch for it?(o/s):"; + $yes_no = ; + chomp($yes_no); + + if ( $yes_no eq "o" ) { + $answers = gen_gpg_id(); + } + else { + print "Are you one of the following people?\n"; + for ( my $i = 0; $i < $entries; $i++ ) { + print ($i+1); + print " - $name[$i] - GPG-ID: $id[$i]\n"; + } + print "choose one of those or \"0\" if yours is not listed:"; + my $answer = ; + chomp($answer); + + if ( $answer == 0 || $answer > $entries ) { + if ( $answer > $entries ) { + print "Your answer did not match anything.\n"; + } + print "please type your GPG_ID:"; + $answers = ; + chomp($answers); + print "You should not forget to import your GPG_ID.\n"; + } + elsif ( $answer <= $entries ) { + print "you said $name[($answer-1)], that means ID: $id[($answer-1)].\n"; + $answers = $id[($answer-1)]; + } + } + } + + print $configfile $answers . "\n"; + print $configfile "#\n"; + print "-------------------------------------------\n"; + + # getting users your sharing your passfile with + print "Do you share your passfile with any other users?(y/n)"; + $yes_no = ; + chomp($yes_no); + print $configfile "## Which users do you share your passfile with? (optional)\n"; + print $configfile "#\n"; + + # generating dummy if you do not share with anybody + if ( $yes_no ne "y" ){ + print $configfile "# USERNAME1 = GPG_ID\n"; + print $configfile "# USERNAME2 = GPG_ID\n"; + $shared_users = "USERNAME1 USERNAME2"; + print $configfile "#\n"; + print $configfile "# "; + } + else { + $shared_users = ""; + } + + # else generating real users + while ( $yes_no eq "y" ){ + + print "What is the name of the person your sharing your file with\n(shouldn't have any spaces in it):"; + $answers = ; + chomp($answers); + print $configfile $answers; + print $configfile " = "; + $shared_users = $shared_users . $answers . " "; + + @gpg_ids = show_gpg_id(); + @name = (); + @id = (); + my $entries = @gpg_ids; + $entries=($entries-1); + for ( my $i = 0; $i < ($entries); $i++ ) { + $name[$i] = (split /\s\s+/,(split /\n/, $gpg_ids[$i])[1])[1]; + $id[$i] = (split /\//,(split /\s/,(split /\n/, $gpg_ids[$i])[0])[3])[1]; + } + + print "Is $answers one of the following people?"; + for ( my $i = 0; $i < $entries; $i++ ) { + print ($i+1); + print " - $name[$i] - GPG-ID: $id[$i]\n"; + } + print "choose one of those or \"0\" if $answers is not listed:"; + my $answer = ; + chomp($answer); + + if ( $answer == 0 || $answer > $entries ) { + if ( $answer > $entries ) { + print "Your answer did not match anything.\n"; + } + print "please give the GPG_ID of $answers:"; + my $gpg_id = ; + chomp($gpg_id); + @gpg_ids = show_gpg_id($gpg_id); + @id = (); + @name = (); + $entries = @gpg_ids; + if ( $entries < 2 ) { + print "the gpg_id could not be found.\n"; + print "I'm trying now to get this key right now.\n"; + my @return = get_gpg_id($gpg_id); + my $status = shift(@return); + my $result = shift(@return); + + if ( $status ) { + if ( $result ) { + print "The following Error came up:\n@return\n"; + } + else { + print "Think receiving the public gpg-key was a success. Check the following output:\n@return\n"; + @gpg_ids = show_gpg_id($gpg_id); + @id = (); + @name = (); + $name[0] = (split /\s\s+/,(split /\n/, $gpg_ids[0])[1])[1]; + $id[0] = (split /\//,(split /\s/,(split /\n/, $gpg_ids[0])[0])[3])[1]; + $entries = @name; + print "You imported the following:\n"; + print "Name: $name[0] - ID: $id[0]\n"; + $answers = $id[0]; + } + + } + else { + print "@return\n"; + } + } + else { + $name[0] = (split /\s\s+/,(split /\n/, $gpg_ids[0])[1])[1]; + $id[0] = (split /\//,(split /\s/,(split /\n/, $gpg_ids[0])[0])[3])[1]; + + $entries = @name; + print "You said the following:\n"; + print "Name: $name[0] - ID: $id[0]\n"; + $answers = $id[0]; + } + } + else { + print "you said $name[($answer-1)], that means ID: $id[($answer-1)].\n"; + $answers = $id[($answer-1)]; + } + + print $configfile $answers . "\n"; + + print "Do you want to add any other person?(y/n)"; + $yes_no = ; + chomp($yes_no); + if ( $yes_no ne "y" ) { + print $configfile "#\n"; + } + + } + print $configfile "TRUSTED_IDS = " . $shared_users . "\n"; + print $configfile "#\n"; + print "-------------------------------------------\n"; + + + # getting the passfile right now + print "Where is your passfile located?(absolute path):"; + $answers = ; + print $configfile "# Specify your PASSFILE here(needed)\n"; + print $configfile "#\n"; + print $configfile "PASSFILE = " . $answers; + print $configfile "#\n"; + print "-------------------------------------------\n"; + + + # asking the shared_passfile thing + print "Do you want to use a shared passfile?\nyou can have a shared passfile beside your local one.\nthat means to specify a networkdrive or anything like this(y/n)"; + $yes_no = ; + chomp $yes_no; + print $configfile "## Specify a Shared PASSFILE here (optional)\n"; + print $configfile "#\n"; + + # generating shared passfile or dummy one + if ( $yes_no eq "y" ){ + print "Where is the SHARD_PASSFILE located?:"; + $answers = ; + print $configfile "SHARED_PASSFILE = " . $answers; + } + else { + print $configfile "# SHARED_PASSFILE = /mnt/network_drive/.shared/spd_data.gpg\n"; + } + print $configfile "#\n"; + print "-------------------------------------------\n"; + + + # Following the color-section + print "Do you want to configure the password-column right now?\nThis entry is printed red on red that nobody looking your shoulder can read it.(y/n)"; + $yes_no = ; + chomp($yes_no); + print $configfile "## define here which lines should be password [red on red] (that nobody which looks on your screen can read it)\n"; + print $configfile "## you can add multiple words here with a whitespace between(if you have whitespaces in your line use double colon :: as whitespace).\n"; + print $configfile "#\n"; + + if ( $yes_no eq "y" ){ + print "What are your password-columns?\nJust write with whitespaces in between if using more than one column\n"; + $answers = ; + print $configfile "PASSWORD = " . $answers; + } + else { + print $configfile "# PASSWORD = Password\n"; + } + print $configfile "#\n"; + + print "Do you want to add columns which shall be printed YELLOW?(y/n)"; + $yes_no = ; + chomp($yes_no); + print $configfile "## here you can define Colors for your lines\n"; + print $configfile "## available statements are \"YELLOW, RED, BLUE, GREEN\"\n"; + print $configfile "#\n"; + + if ( $yes_no eq "y" ){ + print "What are your yellow colored columns?\nJust write with whitespaces in between if using more than one column\n"; + $answers = ; + print $configfile "YELLOW = " . $answers; + } + else { + print $configfile "# YELLOW = ID\n"; + } + print $configfile "#\n"; + + print "Do you want to add columns which shall be printed BLUE?(y/n)"; + $yes_no = ; + chomp($yes_no); + + if ( $yes_no eq "y" ){ + print "What are your blue colored columns?\nJust write with whitespaces in between if using more than one column\n"; + $answers = ; + print $configfile "BLUE = " . $answers; + } + else { + print $configfile "# BLUE = username\n"; + } + print $configfile "#\n"; + + print "Do you want to add columns which shall be printed GREEN?(y/n)"; + $yes_no = ; + chomp($yes_no); + + if ( $yes_no eq "y" ){ + print "What are your green colored columns?\nJust write with whitespaces in between if using more than one column\n"; + $answers = ; + print $configfile "GREEN = " . $answers; + } + else { + print $configfile "# GREEN = accesslink\n"; + } + print $configfile "#\n"; + + print "Do you want to add columns which shall be printed RED?(y/n)"; + $yes_no = ; + chomp($yes_no); + + if ( $yes_no eq "y" ){ + print "What are your red colored columns?\nJust write with whitespaces in between if using more than one column\n"; + $answers = ; + print $configfile "RED = " . $answers; + } + else { + print $configfile "# RED = accessmethod\n"; + } + print $configfile "#\n"; + print "-------------------------------------------\n"; + + + # editor used to edit the passfile + print "Do you want to specify an Editor right now??\nusing vi if not(y/n)"; + $yes_no = ; + chomp($yes_no); + print $configfile "## Which editor do you use to edit files? (optional)\n"; + print $configfile "#\n"; + + + # generating dummy if not specifying this + if ( $yes_no eq "y" ){ + print "Specify the editor you want to use right now:\n"; + $answers = ; + chomp($answers); + print $configfile "EDITOR = \""; + print $configfile "$answers"; + print $configfile "\"\n"; + } + else { + print $configfile "# EDITOR = vi\n"; + } + print $configfile "#\n"; + print "-------------------------------------------\n"; + + close($configfile) || die "can't close $main::GLOBALSETTINGS->{CONFIG_FILE}: $!\n"; + } + +# Generate a sample config-file +# there are no parameters given and it does not return anything + sub default_config + { + if ( -e "$main::GLOBALSETTINGS->{SPD_DIR}" && -d "$main::GLOBALSETTINGS->{SPD_DIR}" ){ + open(my $configfile,">$main::GLOBALSETTINGS->{CONFIG_FILE}") || die "cannot create $main::GLOBALSETTINGS->{CONFIG_FILE}: $!\n"; + print $configfile "# Here are all the default-values +# +## What is your NAME and GPG-ID?(needed) +## +# MYNAME = GPG_ID +# +# YOUR_ID = MYNAME +# +## Which users do you share your passfile with? (optional) +# +# USERNAME1 = GPG_ID +# USERNAME2 = GPG_ID +# +# TRUSTED_IDS = USERNAME1 USERNAME2 +# +## Specify your PASSFILE here(needed) +# +# PASSFILE = $main::GLOBALSETTINGS->{SPD_DIR}/spd_data.gpg +# +## Specify a Shared PASSFILE here (optional) +# +# SHARED_PASSFILE = $main::GLOBALSETTINGS->{HOME}/.shared/spd_data.gpg +# +## define here which lines should be password [red on red] (that nobody which looks on your screen can read it) +## you can add multiple words here with a whitespace between(if you have whitespaces in your line use double colon :: as whitespace). +# +# PASSWORD = Password +# +## here you can define Colors for your lines +## available statements are \"YELLOW, RED, BLUE, GREEN\" +# +# YELLOW = ID +# +# BLUE = Hostname +# +# GREEN = Protocol +# +# RED = Accessmethod Accesslink Username +# +## Which editor do you use to edit files? (optional) +# +# EDITOR = vim +#"; + close($configfile) || die "can't close $main::GLOBALSETTINGS->{CONFIG_FILE}: $!\n"; + } + else { + mkdir("$main::GLOBALSETTINGS->{SPD_DIR}",0755) || die "cannot mkdir $main::GLOBALSETTINGS->{SPD_DIR}: $!\n"; + default_config(); + } + + + } +return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/unix_editing.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_editing.pm new file mode 100644 index 0000000..f22affe --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_editing.pm @@ -0,0 +1,95 @@ +# sub to start editing +# there are no parameters given nor returned. +# it gets his parameters out of global hashes + sub editing + { + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL}) { # check if it is a shared passfile + edit_file($main::GLOBALSETTINGS->{PASSFILE},decrypt_passfile($main::GLOBALSETTINGS->{PASSFILE})); + } + else { + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock" && !$main::GLOBALPARAMETERS->{FORCE} ) { # check if lockfile is created + open (my $lockfile,"<$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock") || die "COULD NOT OPEN LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock: $!. THAT SHOULDN'T HAPPEN!"; + my $current_user = <$lockfile>; + close($lockfile) || die "COULD NOT CLOSE LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock: $!. THAT SHOULDN'T HAPPEN!"; + print "You cannot edit $main::GLOBALSETTINGS->{SHARED_PASSFILE} as it is currently processed by $current_user\ntry --force if you really want to edit it (changes maybe lost)\n"; + } + else { + if ( $main::GLOBALPARAMETERS->{FORCE} ) { # forcing this option deletes the file @ first + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock" ) { + unlink("$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock"); + } + } + open (my $lockfile,">$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock") || die "COULD NOT OPEN LOCKFILE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock for writing: $!.\nDoing this would be insecure\n"; + print $lockfile "$main::GLOBALSETTINGS->{YOUR_NAME} (editing)"; # create lockfile + close($lockfile) || die "COULD NOT CLOSE $main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock after writing: $!.\n that REALLY shouldn't happen!\n"; + edit_file($main::GLOBALSETTINGS->{SHARED_PASSFILE},decrypt_passfile($main::GLOBALSETTINGS->{SHARED_PASSFILE})); + unlink("$main::GLOBALSETTINGS->{SHARED_PASSFILE}.lock"); + compare_passfiles($main::GLOBALSETTINGS->{SHARED_PASSFILE}, $main::GLOBALSETTINGS->{PASSFILE}); + } + } + } + + # procedure to edit the file with your editor + # parameter given is the location of the passfile (first) and the plainpassarray (second) + # return nothin + sub edit_file + { + my ($mktemp_fh, $MKTEMP) = tempfile( UNLINK => 1 ); + close ($mktemp_fh) || die "Could not close temporary filehandle for $MKTEMP. that shouldn't happen\n"; + my $errorcode = 1; + my $passfile = shift; + my @plainpassfile = @_; + my $answer = ""; + + open($mktemp_fh,'>'.$MKTEMP) || die "Open $MKTEMP: $! that shouldn't happen\n"; + print $mktemp_fh @plainpassfile; + close($mktemp_fh) || die "cannot close $MKTEMP. WTF?? that shouldn't happen\n"; + my $md5sum_before_passfile = file_md5_hex($passfile); # get md5sum of passfile before editing tempfile + + my $md5sum_before_tempfile = file_md5_hex($MKTEMP); # get md5sum of tempfile before editing + + while ( $errorcode == 1 ) { + system("$main::GLOBALSETTINGS->{EDITOR} $MKTEMP"); + $errorcode = check_quantity($MKTEMP); # check wether all lines do have same column count + if ( $errorcode == 1 ) { + print "Would you like to go back editing this?(y/n)"; + my $input = ; + chomp($input); + if ( $input eq "n" ) { + $errorcode = 0; + } + } + } + my $md5sum_after_tempfile = file_md5_hex($MKTEMP); # get md5sum of tempfile after editing + + my $md5sum_after_passfile = file_md5_hex($passfile); # get md5sum of passfile after editing tempfile + if ( $md5sum_before_passfile eq $md5sum_after_passfile ) { # passfile did not change + if ( $md5sum_before_tempfile ne $md5sum_after_tempfile ) { # tempfile changed during edit (means it WAS edited) + encrypt_file($MKTEMP,$passfile); # encrypt the new passfile + } + } + else { # the passfile changed during editing tempfile. Someone did force editing it. + while ( $answer ne "y" && $answer ne "n" ) { + print "File has been changed while you were adding entries.\nMaybe someone used --force?\nDo you want to join you changes in?(y/n)\n"; + $answer = ; + chomp($answer); + if ( $answer eq "y" ) { # try to merge those changes in + open(my $mktemp_fh,'<'.$MKTEMP) || die "Open $MKTEMP: $! that shouldn't happen\n"; + @plainpassfile = <$mktemp_fh>; + close($mktemp_fh) || die "cannot close $MKTEMP. that shouldn't happen\n"; + @plainpassfile = join_array_to_file($passfile, @plainpassfile); + encrypt_array($passfile, @plainpassfile); + } + elsif ( $answer eq "n" ) { + print "Did nothing. Hope you did not lose any changes?!?\n"; + } + else { + print "not a valid answer, please try again.\n"; + $answer = ""; + } + } + } + } + return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/lib/perl/5.18.2/SPD/unix_print_results.pm b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_print_results.pm new file mode 100644 index 0000000..90745bf --- /dev/null +++ b/spd-perl/usr/lib/perl/5.18.2/SPD/unix_print_results.pm @@ -0,0 +1,324 @@ +# this sub just introduces the print_results procedure first checking if shared passfile is set +# no parameters needed nothing returned + sub searching + { + if ( !$main::GLOBALSETTINGS->{SHARED_PASSFILE} || $main::GLOBALPARAMETERS->{LOCAL} ) { + print_results($main::GLOBALSETTINGS->{PASSFILE}, @ARGV); + } + else { + if ( -e "$main::GLOBALSETTINGS->{SHARED_PASSFILE}" ) { + compare_passfiles($main::GLOBALSETTINGS->{SHARED_PASSFILE}, $main::GLOBALSETTINGS->{PASSFILE}); + print_results($main::GLOBALSETTINGS->{SHARED_PASSFILE}, @ARGV); + } + else { + die "Shared Passfile $main::GLOBALSETTINGS->{SHARED_PASSFILE} is defined but not there.\nForgot --local?\n"; + } + } + } + +# send searchresults to STDOUT +# it needs the location of the passfile as parameter (first) and the searchword [optional] (second) and returns nothing + sub print_results + { + my $file = shift; + my @plainpassfile = decrypt_passfile($file); + my @temp_id; + my @id; + my $id_string = "ID"; + my @resultset; + my @length_columns; + + my $max_desclength = 0; + if ( !@plainpassfile ) { + die "$file has no DATA?\nTyped Passphrase three times wrong?\n"; + } + + my @description = split(/\t/,$plainpassfile[0]); #save Description + shift ( @plainpassfile ); # delete first Element of Array + + my $quantity_desc = @description; # save Quantity of Array Description + $description[$quantity_desc -1] =~ s/\r//; # to get those windows linefeeds away + + chomp($description[$quantity_desc -1]); # needed to delete the \n + my $quantity_plainpassfile = @plainpassfile; + my $id_counter = 0; + my $searchword = shift(@_); + + for ( my $i = 0; $i < $quantity_plainpassfile; $i++ ) { # get the lines containing the first word i was searching for + my $is_in = string_contains_string($plainpassfile[$i], $searchword); + my $is_in2 = string_contains_string(($i+1), $searchword); + if ( ($is_in) || ($is_in2) ) { + $temp_id[$id_counter] = ($i+1); # write an array containing the id of the match + $resultset[$id_counter] = $plainpassfile[$i]; # write matches into another array + $id_counter++; + } + } + + # the following seems to be crazy but i need it to be done that way because i don't want to lose the ids where the line contains my searchwords + if ( $_[0] ) { # now check if the other words i was searching for are also on + foreach $searchword ( @_ ) { + @plainpassfile = @resultset; + @resultset = (); + @id = (); + $id_counter = 0; + + $quantity_plainpassfile = @plainpassfile; + for ( my $i = 0; $i < $quantity_plainpassfile; $i++ ) { + my $is_in = string_contains_string($plainpassfile[$i], $searchword); + my $is_in2 = string_contains_string($temp_id[$i], $searchword); + if ( ($is_in) || ($is_in2) ) { + $id[$id_counter] = ($temp_id[$i]); + $resultset[$id_counter] = $plainpassfile[$i]; + $id_counter++; + } + } + @temp_id = @id; + } + } + else { + @id = @temp_id; + } + + + # split each line (separated by tab) and write it to STDOUT + my $line_counter=1; + $id_counter = 0; + + if ( $main::GLOBALPARAMETERS->{WIDE} ) { + ############################################################################################## + #### the following is absolutely nasty...don't know if there is any way other doing it....#### + ############################################################################################## + + my $passwordline; + my $red; + my $yellow; + my $blue; + my $green; + + # check length of description and write to length array + for ( my $i = 0; $i < $quantity_desc; $i++ ) { + $length_columns[$i] = 0; + $length_columns[$i] = get_max_length($length_columns[$i],$description[$i]); + } + + # check the length if there is any longer than the one from description + my $quantity_resultset = @resultset; + for ( my $i = 0; $i < $quantity_resultset; $i++ ) { + my @result = split(/\t/,$resultset[$i]); + my $quantity_result = @result; + $result[$quantity_result -1] =~ s/\r//; # to get those windows linefeeds away + chomp($result[$quantity_result -1]); # delete \n + $line_counter++; + + if ( $quantity_desc == $quantity_result ) { + for ( my $x = 0; $x < $quantity_result; $x++ ) { + $length_columns[$x] = get_max_length($length_columns[$x],$result[$x]); + } + } + else { + die "ERROR - Quantity of description does not match quantity of results in line $line_counter\nof your datafile, there are $quantity_result instead of $quantity_desc items, which results in an ERROR"; + } + } + + # check which columns should be colored + for ( my $i = 0; $i < $quantity_resultset; $i++ ) { + if ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{PASSWORDLINE}) ) { + $passwordline = $i; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{RED}) ) { + $red = $i; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{YELLOW}) ){ + $yellow = $i; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{BLUE}) ){ + $blue = $i; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{GREEN}) ){ + $green = $i; + } + } + + + # print Description in the right length + print "$id_string\t"; + for ( my $i = 0; $i < $quantity_desc; $i++ ) { + my @return = make_strings_equal($length_columns[$i],$description[$i]); + if ( $i < $quantity_desc-1 ) { + print "@return\t"; + } + else { + print "@return\n"; + } + } + + # adjust length of Resultset + for ( my $i = 0; $i < $quantity_resultset; $i++ ) { + my @result = split(/\t/,$resultset[$i]); + my $quantity_result = @result; + $result[$quantity_result -1] =~ s/\r//; # to get those windows linefeeds away + chomp($result[$quantity_result -1]); # delete \n + for ( my $x = 0; $x < $quantity_result; $x++ ) { + my @return = make_strings_equal($length_columns[$x],$result[$x]); + $result[$x] = "@return"; + } + $resultset[$i] = join("\t",@result); + } + + # print Resultset + for ( my $i = 0; $i < $quantity_resultset; $i++ ) { + my @result = split(/\t/,$resultset[$i]); + my $quantity_result = @result; + $result[$quantity_result -1]=~ s/\r//; # remove windows linefeed + + if ( string_equals_array($id_string,$main::GLOBALSETTINGS->{RED}) ) { + print BOLD RED "$id[$i]"; + print "\t"; + } + elsif ( string_equals_array($id_string,$main::GLOBALSETTINGS->{YELLOW}) ){ + print BOLD YELLOW "$id[$i]"; + print "\t"; + } + elsif ( string_equals_array($id_string,$main::GLOBALSETTINGS->{BLUE}) ){ + print BOLD BLUE "$id[$i]"; + print "\t"; + } + elsif ( string_equals_array($id_string,$main::GLOBALSETTINGS->{GREEN}) ){ + print GREEN BOLD "$id[$i]"; + print "\t"; + } + else { + print BOLD "$id[$i]"; + print "\t"; + } + + + chomp($result[$quantity_result -1]); # delete \n + for ( my $x = 0; $x < ($quantity_result-1); $x++ ) { + if ( $passwordline && $passwordline eq $x ) { + print RED ON_RED "$result[$x]\t"; + } + elsif ( $red && $red eq $x ) { + print BOLD RED "$result[$x]\t"; + } + elsif ( $yellow && $yellow eq $x ) { + print BOLD YELLOW "$result[$x]\t"; + } + elsif ( $blue && $blue eq $x ){ + print BOLD BLUE "$result[$x]\t"; + } + elsif ( $green && $green eq $x ){ + print GREEN BOLD "$result[$x]\t"; + } + else { + print BOLD "$result[$x]\t"; + } + } + + if ( $passwordline && $passwordline eq ($quantity_result-1) ) { + print RED ON_RED "$result[$quantity_result -1]\n"; + } + elsif ( $red && $red eq ($quantity_result-1) ) { + print BOLD RED "$result[$quantity_result -1]\n"; + } + elsif ( $yellow && $yellow eq ($quantity_result-1) ) { + print BOLD YELLOW "$result[$quantity_result -1]\n"; + } + elsif ( $blue && $blue eq ($quantity_result-1) ){ + print BOLD BLUE "$result[$quantity_result -1]\n"; + } + elsif ( $green && $green eq ($quantity_result-1) ){ + print GREEN BOLD "$result[$quantity_result -1]\n"; + } + else { + print BOLD "$result[$quantity_result -1]\n"; + } + } + + } + # back to normal operation *sigh* + else { + # we shall norm the description-output before that we do not get shifted output + # + $max_desclength = get_max_length("0",@description); + @description = make_strings_equal($max_desclength,@description); + + # make ID also the same length + my $length_desc = length $id_string; + my $missing = $max_desclength - $length_desc; + for ( my $x = 0; $x < $missing; $x++ ) { + $id_string = $id_string . " "; + } + + foreach my $line (@resultset){ + my @result = split(/\t/,$line); + my $quantity_result = @result; + $result[$quantity_result -1] =~ s/\r//; # to get those windows linefeeds away + chomp($result[$quantity_result -1]); # delete \n + $line_counter++; + if ( $quantity_desc == $quantity_result ) { + print "$id_string : "; + if ( string_equals_array($id_string,$main::GLOBALSETTINGS->{RED}) ) { + print BOLD RED "$id[$id_counter]"; + print "\n"; + } + elsif ( string_equals_array($id_string,$main::GLOBALSETTINGS->{YELLOW}) ){ + print BOLD YELLOW "$id[$id_counter]"; + print "\n"; + } + elsif ( string_equals_array($id_string,$main::GLOBALSETTINGS->{BLUE}) ){ + print BOLD BLUE "$id[$id_counter]"; + print "\n"; + } + elsif ( string_equals_array($id_string,$main::GLOBALSETTINGS->{GREEN}) ){ + print GREEN BOLD "$id[$id_counter]"; + print "\n"; + } + else { + print BOLD "$id[$id_counter]"; + print "\n"; + } + + + + for ( my $i = 0; $i < $quantity_desc; $i++ ) { + + print "$description[$i] : "; + + if ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{PASSWORDLINE}) ) { + print RED ON_RED "$result[$i]"; + print "\n"; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{RED}) ) { + print BOLD RED "$result[$i]"; + print "\n"; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{YELLOW}) ){ + print BOLD YELLOW "$result[$i]"; + print "\n"; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{BLUE}) ){ + print BOLD BLUE "$result[$i]"; + print "\n"; + } + elsif ( string_equals_array($description[$i],$main::GLOBALSETTINGS->{GREEN}) ){ + print GREEN BOLD "$result[$i]"; + print "\n"; + } + else { + print BOLD "$result[$i]"; + print "\n"; + } + } + $id_counter++; + } + else { + die "ERROR - Quantity of description does not match quantity of results in line $line_counter\nof your datafile, there are $quantity_result instead of $quantity_desc items, which results in an ERROR"; + } + print "\n"; + } + } + } + return 1; + +# vim:tabstop=3 diff --git a/spd-perl/usr/share/doc/spd-perl/NEWS.gz b/spd-perl/usr/share/doc/spd-perl/NEWS.gz new file mode 100644 index 0000000000000000000000000000000000000000..9189214a15c6c90185d61a52527420d7b4fcc4f2 GIT binary patch literal 151 zcmV;I0BHXoiwFP!0000217*!I3&KDQhT*-xBC~^tqiexg5Zq%gy$0Ick)+u3*V_}? zLD!Gx + + -- unknown Sun, 14 Sep 2014 10:38:11 -0400 diff --git a/spd-perl/usr/share/doc/spd-perl/changelog.Debian.gz b/spd-perl/usr/share/doc/spd-perl/changelog.Debian.gz new file mode 100644 index 0000000000000000000000000000000000000000..0dd6d5d776e7dd84bc9ac5665d6036735b445530 GIT binary patch literal 167 zcmV;Y09gMYiwFP!000020~L+E4uUWkMR%U!CN5yCX_3Jo5)&sj6MX^DPi!n-Nq<6k zd+S}!na=g|OU&d9a=9;sDiGO+elT=GbR+R|JsZ1Z8L&miI_TcOk)hrb@~g3)e2opK z6+rVRv`6?5hB$)bG?0URW3|ztd)(TT5+c2P*)EJGkPn*2i<^84+#~OxD%@#CDU&E! VAC9$B5VDdo`vIRv-P*1I003U;NhAOO literal 0 HcmV?d00001 diff --git a/spd-perl/usr/share/doc/spd-perl/copyright b/spd-perl/usr/share/doc/spd-perl/copyright new file mode 100644 index 0000000..da3434e --- /dev/null +++ b/spd-perl/usr/share/doc/spd-perl/copyright @@ -0,0 +1,49 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: spd-perl +Source: + +Files: * +Copyright: 2008 treibholz + 2008 Z3po + 2008 badticket +License: GPL-2 + This package 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; version 2 of the License. + . + This package 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 + 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, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +# If you want to use GPL v2 or later for the /debian/* files use +# the following clauses, or change it to suit. Delete these two lines +Files: debian/* +Copyright: 2014 Lisa Maginnis +License: GPL-2 + This package 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 of the License, or + (at your option) any later version. + . + This package 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 + 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, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + +# Please also look if there are files or directories which have a +# different copyright/license attached and list them here. +# Please avoid to pick license terms that are more restrictive than the +# packaged work, as it may make Debian's contributions unacceptable upstream. diff --git a/spd-perl/usr/share/man/de/man1/spd.1.gz b/spd-perl/usr/share/man/de/man1/spd.1.gz new file mode 100644 index 0000000000000000000000000000000000000000..c929ddee7916015a376fe37fb108055fe9d1f363 GIT binary patch literal 3311 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 literal 0 HcmV?d00001 diff --git a/spd-perl/usr/share/man/de/man5/spd.conf.5.gz b/spd-perl/usr/share/man/de/man5/spd.conf.5.gz new file mode 100644 index 0000000000000000000000000000000000000000..40239448d97200c152c48dac927dccba6cb1aa58 GIT binary patch literal 3912 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 literal 0 HcmV?d00001 diff --git a/spd-perl/usr/share/man/man1/spd.1.gz b/spd-perl/usr/share/man/man1/spd.1.gz new file mode 100644 index 0000000000000000000000000000000000000000..5c829927ee1bf8c114d08e0ee44252e9b363113f GIT binary patch literal 3199 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 MFa0;QB4{iC00dv_mjD0& literal 0 HcmV?d00001 -- 2.25.1