diff --git a/lib/SLUB/LZA/Rosetta/TA.pm b/lib/SLUB/LZA/Rosetta/TA.pm index 45f8a646216a671701c81d694a8e75a8a01b9be2..87fd344f33fecbc7d7a44ebcfee74d05094646bd 100644 --- a/lib/SLUB/LZA/Rosetta/TA.pm +++ b/lib/SLUB/LZA/Rosetta/TA.pm @@ -11,12 +11,14 @@ use feature qw(say); use Regexp::Optimizer; use IO::Zlib; use Text::CSV_PP; +use SLUB::LZA::Rosetta::TA::Crypt; # ABSTRACT: main module for ta-tool our %config; our %cache; our $cache_path; +our $SALT = pack("H16", "There is no security by obscurity!"); BEGIN{ my $home = path($ENV{'HOME'}); if ($home->is_dir() && !$home->is_rootdir) { @@ -24,6 +26,10 @@ BEGIN{ our $config_file = $config_path; if ($config_path->is_file) { %config = YAML::LoadFile($config_path); + if (defined $config{password}) { + warn "HINT: The password was stored in config file!"; + $config{decrypted_password} = SLUB::LZA::Rosetta::TA::Crypt::decrypt($config{password}); + } } $cache_path = $home->child('.cache')->child('ta-tool.cache'); if ($cache_path->is_file and -s $cache_path < 8192*1024) { # if size > 8MB, write new at end, see END{}-block diff --git a/lib/SLUB/LZA/Rosetta/TA/Command/init.pm b/lib/SLUB/LZA/Rosetta/TA/Command/init.pm index 4d1fafb4368435b702cd11d83cb069b600c24bf0..8b4fc55fda43a042639f71c436ac140b472f21bf 100644 --- a/lib/SLUB/LZA/Rosetta/TA/Command/init.pm +++ b/lib/SLUB/LZA/Rosetta/TA/Command/init.pm @@ -4,6 +4,10 @@ use warnings; use SLUB::LZA::Rosetta::TA -command; use YAML qw(DumpFile); use feature qw(say); +use IO::Prompt; +use Crypt::Mode::CBC; +use Path::Tiny; + sub abstract {"Initialize $0";} sub description {"Initialize $0, preparing config"} @@ -12,6 +16,7 @@ sub opt_spec { ["verbose|v" => "enable verbose output"], ["rosettahost|r=s" => "host adress where Rosetta runs", {required=>1}], ["logdir|l=s" => "logdir where rosetta stores it server log files", {required=>1}], + ["authentication|a" => "enable authentification (needed if Rosetta's general parameter 'sru_authentication=true'), password is stored salted only in config file!", {required=>0}] ); } sub validate_args { @@ -25,12 +30,32 @@ sub execute { my %config; $config{host} = $opt->{rosettahost}; $config{logdir} = $opt->{logdir}; + if (defined $opt->{authentication}) { + warn "HINT: The password will stored in config file!"; + my $user = prompt('User:' ); + $config{user} = "$user"; + my $institution = prompt('Institution:' ); + $config{institution} = "$institution"; + RETRY: + my $passwd1 = prompt ('Password:', -echo=>"*"); + my $passwd2 = prompt ('Password, again:', -echo=>"*"); + if ($passwd1 ne $passwd2) { + say "you typed different passwords, retry"; + goto RETRY; + } + $config{password} = SLUB::LZA::Rosetta::TA::Crypt::encrypt("$passwd1"); + } if (defined $SLUB::LZA::Rosetta::TA::config_file) { if (defined $opt->{verbose}) { say "store config in $SLUB::LZA::Rosetta::TA::config_file"; } - YAML::DumpFile($SLUB::LZA::Rosetta::TA::config_file, %config); + my $file = path($SLUB::LZA::Rosetta::TA::config_file); + $file->touch(); + $file->chmod("0600"); + my $fh = path($SLUB::LZA::Rosetta::TA::config_file)->filehandle({exclusive => 0}, ">"); + YAML::DumpFile($fh, %config); + $fh->close; } } -1; \ No newline at end of file +1; diff --git a/lib/SLUB/LZA/Rosetta/TA/Command/log.pm b/lib/SLUB/LZA/Rosetta/TA/Command/log.pm index 6db540b968402933a6cf9183e172da1f3d55fe0e..c9dc7d0eaf7a9753ae72ff086ac15318403ea5af 100644 --- a/lib/SLUB/LZA/Rosetta/TA/Command/log.pm +++ b/lib/SLUB/LZA/Rosetta/TA/Command/log.pm @@ -43,6 +43,8 @@ sub opt_spec { ["level=s@" => "levels to search for. Levels could be: 'error', 'warn', 'info', 'debug'. You could use multiple levels by repeating"], ["match=s" => "perl regex to search for" => {default=>".*"}], ["trace=s" => "trace a sip/IE with given ID (SIP-ID or Deposit-ID or IE PID)"], + ["user|u:s" => "user if authentication needed (optional, depends on settings in Rosetta's global parameter: sru_authentication=true)", {required=>0}], + ["password|p:s" => "password if authentication needed (optional, depends on settings in Rosetta's global parameter: sru_authentication=true)", {required=>0}], ); } diff --git a/lib/SLUB/LZA/Rosetta/TA/Command/search.pm b/lib/SLUB/LZA/Rosetta/TA/Command/search.pm index 097ca4965e641179cf2eee07d04c4d4f3bb9e3f9..3302bc4c6a5003617536e3febc9b61b3f514b98b 100644 --- a/lib/SLUB/LZA/Rosetta/TA/Command/search.pm +++ b/lib/SLUB/LZA/Rosetta/TA/Command/search.pm @@ -79,7 +79,7 @@ sub execute { $startrecord = $opt->{startrecord}; } my $query = SLUB::LZA::Rosetta::TA::common_sru::prepare_query($opt); - my $response = SLUB::LZA::Rosetta::TA::SRU::sru_search('ie', $query, $startrecord, $maxrecords, $opt->{verbose}); + my $response = SLUB::LZA::Rosetta::TA::SRU::sru_search('ie', $query, $startrecord, $maxrecords, $opt->{verbose}, $opt->{user}, $opt->{password}); say $response; } diff --git a/lib/SLUB/LZA/Rosetta/TA/Crypt.pm b/lib/SLUB/LZA/Rosetta/TA/Crypt.pm new file mode 100644 index 0000000000000000000000000000000000000000..ea1e3d5b1e369f53b296b9c8a59545287704a81e --- /dev/null +++ b/lib/SLUB/LZA/Rosetta/TA/Crypt.pm @@ -0,0 +1,27 @@ +package SLUB::LZA::Rosetta::TA::Crypt; +use strict; +use warnings; +use Crypt::Mode::CBC; + +our $salt = pack("H16", "There is no security by obscurity!"); +sub encrypt { + my $what = shift; + my $iv = "74387112"; # length needs to be of 8 + my $c = Crypt::Mode::CBC->new('Blowfish'); + my $password = $c->encrypt($what, $salt, $iv); + my $password_hex = unpack("H*", $password); + return $password_hex; +} + +sub decrypt { + my $password_hex = shift; + my $c = Crypt::Mode::CBC->new('Blowfish'); + if (defined $password_hex) { + my $iv = "74387112"; # length needs to be of 8 + my $password = pack("H*", $password_hex); + my $decrypted = $c->decrypt($password, $salt, $iv); + return $decrypted; + } + return; +} +1; diff --git a/lib/SLUB/LZA/Rosetta/TA/SRU.pm b/lib/SLUB/LZA/Rosetta/TA/SRU.pm index 26a19eb4df2ded6cfc63c0b4be897c71fdd94dfb..2e9ec0a0a43e5fcaed5e8b2cab7eccd1dc121e14 100644 --- a/lib/SLUB/LZA/Rosetta/TA/SRU.pm +++ b/lib/SLUB/LZA/Rosetta/TA/SRU.pm @@ -2,6 +2,9 @@ package SLUB::LZA::Rosetta::TA::SRU; use strict; use warnings; use feature qw(say); +use LWP::Authen::Basic; +use LWP::UserAgent; +use Carp; sub url_encode_simple { my $string = shift; @@ -38,19 +41,34 @@ sub sru_search { $ua->agent("MyApp/0.1 "); $ua->timeout(3600);#1h $ua->default_headers->push_header('Accept-Encoding' => 'br, lzma, bzip2, gzip, compressed, deflate'); + + $ua->ssl_opts( verify_hostname=>1, # SSL_ca_path => '/etc/ssl/', ); + if ($is_verbose) { say "searchurl = $sru"; } - my $req = $ua->get($sru); - if ($req->is_success) { - my $xres = $req->decoded_content; - return $xres; - } else { - croak ("Error was: ".$req->status_line()); + foreach my $retry (1 .. 2) { + my $req = $ua->get($sru); + if ($req->is_success) { + my $xres = $req->decoded_content; + return $xres; + } else { + if ($retry == 1 and defined $SLUB::LZA::Rosetta::TA::config{"decrypted_password"} ) { + my $user = $SLUB::LZA::Rosetta::TA::config{"user"}; + my $inst = $SLUB::LZA::Rosetta::TA::config{"institution"}; + my $password = $SLUB::LZA::Rosetta::TA::config{"decrypted_password"}; + my $preauth = "$user-institutionCode-$inst:$password"; + my $auth = MIME::Base64::encode_base64($preauth , ''); + $ua->default_headers->push_header('Authorization' => $auth); + warn "Retry using authentication"; + } else { + croak("Error was: " . $req->status_line()); + } + } } }