Package: trocla Version: 0.2.3-1 Severity: normal Tags: patch pending Dear maintainer,
I've prepared an NMU for trocla (versioned as 0.3.0-0.1) and uploaded it to DELAYED/10. Please feel free to tell me if I should delay it longer. I also uploaded it to experimental, given that we're in a freeze, as a precaution, in case you want to just cherry-pick the two patches to just fix the RC bugs. But considering that 0.2.3 is pretty broken, I suspect that wouldn't be a good idea anyways. Note that this diff includes a pile of changes that had accumulated in the git repository on salsa and are therefore not only my changes. My work may be more easily reviewed here: https://salsa.debian.org/anarcat/trocla/-/commits/debian/experimental/ You can also see the pipeline has been fixed by those commits here: https://salsa.debian.org/anarcat/trocla/-/pipelines/251950 Regards.
diff -Nru trocla-0.2.3/bin/trocla trocla-0.3.0/bin/trocla --- trocla-0.2.3/bin/trocla 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/bin/trocla 2021-05-04 15:31:47.000000000 -0400 @@ -47,18 +47,20 @@ end.parse! def create(options) - Trocla.new(options.delete(:config_file)).password( + [ Trocla.new(options.delete(:config_file)).password( options.delete(:trocla_key), options.delete(:trocla_format), options.merge(YAML.load(options.delete(:other_options).shift.to_s)||{}) - ) + ) , 0 ] end def get(options) - Trocla.new(options.delete(:config_file)).get_password( + res = Trocla.new(options.delete(:config_file)).get_password( options.delete(:trocla_key), - options.delete(:trocla_format) + options.delete(:trocla_format), + options.merge(YAML.load(options.delete(:other_options).shift.to_s)||{}) ) + [ res, res.nil? ? 1 : 0 ] end def set(options) if options.delete(:ask_password) @@ -67,7 +69,7 @@ pwd2 = ask('Repeat password: ') { |q| q.echo = 'x' }.to_s unless password == pwd2 STDERR.puts 'Passwords did not match, exiting!' - exit 1 + return [ nil, 1 ] end else password = options.delete(:password) || STDIN.read.chomp @@ -78,29 +80,29 @@ value = if no_format password else - trocla.formats(format).format(password, options.delete(:other_options).shift.to_s) + trocla.formats(format).format(password, (YAML.load(options.delete(:other_options).shift.to_s)||{})) end trocla.set_password( options.delete(:trocla_key), format, value ) - '' + [ '', 0 ] end def reset(options) - Trocla.new(options.delete(:config_file)).reset_password( + [ Trocla.new(options.delete(:config_file)).reset_password( options.delete(:trocla_key), options.delete(:trocla_format), options.merge(YAML.load(options.delete(:other_options).shift.to_s)||{}) - ) + ), 0 ] end def delete(options) - Trocla.new(options.delete(:config_file)).delete_password( + [ Trocla.new(options.delete(:config_file)).delete_password( options.delete(:trocla_key), options.delete(:trocla_format) - ) + ), 0 ] end def formats(options) @@ -125,7 +127,8 @@ options[:other_options] = ARGV check_format(options[:trocla_format]) unless ['delete','formats'].include?(action) begin - if result = send(action,options) + result, excode = send(action,options) + if result puts result.is_a?(String) ? result : result.inspect end rescue Exception => e @@ -136,6 +139,7 @@ raise e if options[:trace] exit 1 end + exit excode.nil? ? 0 : excode else STDERR.puts "Please supply one of the following actions: #{actions.join(', ')}" STDERR.puts "Use #{$0} --help to get a list of options for these actions" diff -Nru trocla-0.2.3/CHANGELOG.md trocla-0.3.0/CHANGELOG.md --- trocla-0.2.3/CHANGELOG.md 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/CHANGELOG.md 2021-05-04 15:31:47.000000000 -0400 @@ -1,5 +1,14 @@ # Changelog +## to 0.3.0 + +* Add open method to be able to immediately close a trocla store after using it - thanks martinpfeiffer +* Add typesafe charset - thanks hggh +* Support cost option for bcrypt +* address concurrency corner cases, when 2 concurrent threads or even processes + are currently calculating the same (expensive) format. +* parse additional options on cli (#39 & #46) - thanks fe80 + ## to 0.2.3 1. Add extended CA validity profiles diff -Nru trocla-0.2.3/debian/changelog trocla-0.3.0/debian/changelog --- trocla-0.2.3/debian/changelog 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/changelog 2021-05-04 15:32:32.000000000 -0400 @@ -1,3 +1,39 @@ +trocla (0.3.0-0.1) experimental; urgency=medium + + [ Antoine Beaupré ] + * Non-maintainer upload. + * New upstream release (Closes: #974697) + * Remove no-pending_for patch: dependency packaged in Debian and added + to Build-Depends. + * remove fix_version.patch: just ship the version instead of chasing the + version number in a patch (!?) + * disable the failing test, after discussion with upstream (Closes: + #982154) + * change section to admin (Closes: #832261) + * expand search path for sample config file to fix autopkgtest (Closes: + #830240) + + [ Cédric Boutillier ] + * Bump debhelper compatibility level to 9 + * Use https:// in Vcs-* fields + * Run wrap-and-sort on packaging files + * Use new default gem2deb Rakefile to run the tests + + [ Utkarsh Gupta ] + * Add salsa-ci.yml + + [ Debian Janitor ] + * Use secure copyright file specification URI. + * Use secure URI in debian/watch. + * Bump debhelper from deprecated 9 to 12. + * Set debhelper-compat version in Build-Depends. + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. + * Update Vcs-* headers from URL redirect. + * Use canonical URL in Vcs-Git. + + -- Antoine Beaupré <anar...@debian.org> Tue, 04 May 2021 15:32:32 -0400 + trocla (0.2.3-1) unstable; urgency=medium * Team upload. diff -Nru trocla-0.2.3/debian/compat trocla-0.3.0/debian/compat --- trocla-0.2.3/debian/compat 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/compat 1969-12-31 19:00:00.000000000 -0500 @@ -1 +0,0 @@ -7 diff -Nru trocla-0.2.3/debian/control trocla-0.3.0/debian/control --- trocla-0.2.3/debian/control 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/control 2021-05-04 15:32:32.000000000 -0400 @@ -1,19 +1,20 @@ Source: trocla -Section: ruby +Section: admin Priority: optional -Maintainer: Debian Ruby Extras Maintainers <pkg-ruby-extras-maintain...@lists.alioth.debian.org> +Maintainer: Debian Ruby Team <pkg-ruby-extras-maintain...@lists.alioth.debian.org> Uploaders: Jonas Genannt <gena...@debian.org> -Build-Depends: debhelper (>= 7.0.50~), +Build-Depends: debhelper-compat (= 12), gem2deb, rake, ruby-bcrypt, ruby-highline, + ruby-mocha, ruby-moneta, ruby-rspec, - ruby-mocha + ruby-rspec-pending-for, Standards-Version: 3.9.7 -Vcs-Git: git://anonscm.debian.org/pkg-ruby-extras/trocla.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-ruby-extras/trocla.git +Vcs-Git: https://salsa.debian.org/ruby-team/trocla.git +Vcs-Browser: https://salsa.debian.org/ruby-team/trocla Homepage: https://github.com/duritong/trocla Testsuite: autopkgtest-pkg-ruby XS-Ruby-Versions: all diff -Nru trocla-0.2.3/debian/copyright trocla-0.3.0/debian/copyright --- trocla-0.2.3/debian/copyright 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/copyright 2021-05-04 15:32:32.000000000 -0400 @@ -1,4 +1,4 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: trocla Source: https://github.com/duritong/trocla diff -Nru trocla-0.2.3/debian/patches/830240.patch trocla-0.3.0/debian/patches/830240.patch --- trocla-0.2.3/debian/patches/830240.patch 1969-12-31 19:00:00.000000000 -0500 +++ trocla-0.3.0/debian/patches/830240.patch 2021-05-04 15:32:32.000000000 -0400 @@ -0,0 +1,35 @@ +Description: load trocla from installed code + In autopkgtest, we fail to find the trocla config file because + "gem2deb-test-runner will remove lib directory from source tree + during tests", according to: + . + https://wiki.debian.org/Teams/Ruby/Packaging/Tests + . + The workaround is to find out where we loaded trocla from and use + *that* as a base directory. +Author: Antoine Beaupré <anar...@debian.org> +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=830240 +Origin: Debian +Last-Update: 2021-05-04 +Forwarded: https://github.com/duritong/trocla/pull/64 + +Index: b/spec/spec_helper.rb +=================================================================== +--- a/spec/spec_helper.rb 2021-05-04 20:40:41.480961893 -0400 ++++ b/spec/spec_helper.rb 2021-05-04 20:41:20.300799490 -0400 +@@ -225,7 +225,14 @@ RSpec.shared_examples 'store_validation' + end + + def default_config +- @default_config ||= YAML.load(File.read(File.expand_path(base_dir+'/lib/trocla/default_config.yaml'))) ++ config_path = false ++ for p in [ ++ File.expand_path(base_dir+'/lib/trocla/default_config.yaml'), ++ File.expand_path(File.dirname($LOADED_FEATURES.grep(/trocla.rb/)[0])+'/trocla/default_config.yaml'), ++ ] do ++ config_path = p if File.exists?(p) ++ end ++ @default_config ||= YAML.load(File.read(config_path)) + end + + def test_config diff -Nru trocla-0.2.3/debian/patches/fix_version.patch trocla-0.3.0/debian/patches/fix_version.patch --- trocla-0.2.3/debian/patches/fix_version.patch 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/patches/fix_version.patch 1969-12-31 19:00:00.000000000 -0500 @@ -1,27 +0,0 @@ -Description: do not ship VERSION file on top library level -Author: Jonas Genannt <gena...@debian.org> -Forwared: not-needed - ---- a/lib/trocla/version.rb -+++ b/lib/trocla/version.rb -@@ -2,16 +2,11 @@ - class Trocla - class VERSION - version = {} -- File.read(File.join(File.dirname(__FILE__), '../', 'VERSION')).each_line do |line| -- type, value = line.chomp.split(":") -- next if type =~ /^\s+$/ || value =~ /^\s+$/ -- version[type] = value -- end - -- MAJOR = version['major'] -- MINOR = version['minor'] -- PATCH = version['patch'] -- BUILD = version['build'] -+ MAJOR = 0 -+ MINOR = 2 -+ PATCH = 3 -+ BUILD = '' - - STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.') - diff -Nru trocla-0.2.3/debian/patches/no-pending_for trocla-0.3.0/debian/patches/no-pending_for --- trocla-0.2.3/debian/patches/no-pending_for 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/patches/no-pending_for 1969-12-31 19:00:00.000000000 -0500 @@ -1,65 +0,0 @@ -Index: trocla/spec/trocla/formats/x509_spec.rb -=================================================================== ---- trocla.orig/spec/trocla/formats/x509_spec.rb -+++ trocla/spec/trocla/formats/x509_spec.rb -@@ -184,18 +184,14 @@ describe "Trocla::Format::X509" do - ca2 = OpenSSL::X509::Certificate.new(ca2_str) - expect(ca2.issuer.to_s).to eq(@ca.subject.to_s) - expect((Date.parse(ca2.not_after.localtime.to_s) - Date.today).to_i).to eq(365) -- pending_for(:engine => 'jruby',:reason => 'NameConstraints verification seem to be broken in jRuby: https://github.com/jruby/jruby/issues/3502') do - expect(verify(@ca,ca2)).to be true -- end - - expect(ca2.extensions.find{|e| e.oid == 'basicConstraints' }.value).to eq('CA:TRUE') - ku = ca2.extensions.find{|e| e.oid == 'keyUsage' }.value - expect(ku).to match(/Certificate Sign/) - expect(ku).to match(/CRL Sign/) - nc = ca2.extensions.find{|e| e.oid == 'nameConstraints' }.value -- pending_for(:engine => 'jruby',:reason => 'NameConstraints verification seem to be broken in jRuby: https://github.com/jruby/jruby/issues/3502') do - expect(nc).to match(/Permitted:\n DNS:example.com\n DNS:bla.example.net/) -- end - valid_cert_str = @trocla.password('myvalidexamplecert','x509', { - 'subject' => '/C=ZZ/O=Trocla Inc./CN=foo.example.com/emailAddress=exam...@example.com', - 'ca' => 'mycert_with_nc' -@@ -224,9 +220,7 @@ describe "Trocla::Format::X509" do - ca2 = OpenSSL::X509::Certificate.new(ca2_str) - expect(ca2.issuer.to_s).to eq(@ca.subject.to_s) - expect((Date.parse(ca2.not_after.localtime.to_s) - Date.today).to_i).to eq(365) -- pending_for(:engine => 'jruby',:reason => 'NameConstraints verification seem to be broken in jRuby: https://github.com/jruby/jruby/issues/3502') do - expect(verify(@ca,ca2)).to be true -- end - - expect(ca2.extensions.find{|e| e.oid == 'basicConstraints' }.value).to eq('CA:TRUE') - ku = ca2.extensions.find{|e| e.oid == 'keyUsage' }.value -@@ -245,9 +239,7 @@ describe "Trocla::Format::X509" do - if %x{openssl version} =~ /1\.0\.[2-9]/ - expect(verify([@ca,ca2],valid_cert)).to be true - else -- skip_for(:engine => 'ruby',:reason => 'NameConstraints verification is broken on older openssl versions https://rt.openssl.org/Ticket/Display.html?id=3562') do - expect(verify([@ca,ca2],valid_cert)).to be true -- end - end - - false_cert_str = @trocla.password('myfalseexamplecert','x509', { -@@ -277,9 +269,7 @@ describe "Trocla::Format::X509" do - cert2 = OpenSSL::X509::Certificate.new(cert2_str) - expect(cert2.issuer.to_s).to eq(ca2.subject.to_s) - expect((Date.parse(cert2.not_after.localtime.to_s) - Date.today).to_i).to eq(365) -- skip_for(:engine => 'jruby',:reason => 'Chained CA validation seems to be broken on jruby atm.') do - expect(verify([@ca,ca2],cert2)).to be true -- end - end - - it 'respects all options' do -Index: trocla/spec/spec_helper.rb -=================================================================== ---- trocla.orig/spec/spec_helper.rb -+++ trocla/spec/spec_helper.rb -@@ -1,7 +1,6 @@ - $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) - $LOAD_PATH.unshift(File.dirname(__FILE__)) - require 'rspec' --require 'rspec/pending_for' - require 'yaml' - require 'trocla' - diff -Nru trocla-0.2.3/debian/patches/series trocla-0.3.0/debian/patches/series --- trocla-0.2.3/debian/patches/series 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/patches/series 2021-05-04 15:32:32.000000000 -0400 @@ -1,2 +1,2 @@ -fix_version.patch -no-pending_for +830240.patch +skip-test-982154-2e8082c.patch diff -Nru trocla-0.2.3/debian/patches/skip-test-982154-2e8082c.patch trocla-0.3.0/debian/patches/skip-test-982154-2e8082c.patch --- trocla-0.2.3/debian/patches/skip-test-982154-2e8082c.patch 1969-12-31 19:00:00.000000000 -0500 +++ trocla-0.3.0/debian/patches/skip-test-982154-2e8082c.patch 2021-05-04 15:32:32.000000000 -0400 @@ -0,0 +1,38 @@ +Description: OpenSSL 1.1.1h changed the way self-signed certs work + It is not clear yet why, but this started failing in + bullseye. Upstream recommends skipping the test until the figure out + the problem. +Origin: upstream +Bug: https://github.com/duritong/trocla/issues/63 +Bug-Debian: https://bugs.debian.org/982154 +Last-Update: 2021-05-04 + +From 2e8082c994a245cc27c8ed1b60d76adcb4f5a679 Mon Sep 17 00:00:00 2001 +From: mh <m...@immerda.ch> +Date: Wed, 5 May 2021 00:18:24 +0200 +Subject: [PATCH] fix #63 - skip self-signed cert verification until openssl + behavior change has been clarified + +--- + spec/trocla/formats/x509_spec.rb | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/spec/trocla/formats/x509_spec.rb b/spec/trocla/formats/x509_spec.rb +index 299f807..a3309d4 100644 +--- a/spec/trocla/formats/x509_spec.rb ++++ b/spec/trocla/formats/x509_spec.rb +@@ -44,7 +44,13 @@ def verify(ca,cert) + expect(cert.public_key.n.num_bytes * 8).to eq(4096) + expect((Date.parse(cert.not_after.localtime.to_s) - Date.today).to_i).to eq(365) + # it's a self signed cert and NOT a CA +- expect(verify(cert,cert)).to be false ++ if Gem::Version.new(%x{openssl version}.split(' ')[1]) > Gem::Version.new('1.1.1g') ++ skip_for(:engine => 'ruby',:reason => 'Requires clarification in behavior change on openssl side: https://github.com/openssl/openssl/issues/15146') do ++ expect(verify(cert,cert)).to be false ++ end ++ else ++ expect(verify(cert,cert)).to be false ++ end + + v = cert.extensions.find{|e| e.oid == 'basicConstraints' }.value + expect(v).to eq('CA:FALSE') diff -Nru trocla-0.2.3/debian/ruby-tests.rake trocla-0.3.0/debian/ruby-tests.rake --- trocla-0.2.3/debian/ruby-tests.rake 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/ruby-tests.rake 2021-05-04 15:32:32.000000000 -0400 @@ -1,7 +1,5 @@ -require 'rspec/core/rake_task' +require 'gem2deb/rake/spectask' -RSpec::Core::RakeTask.new(:spec) do |spec| +Gem2Deb::Rake::RSpecTask.new do |spec| spec.pattern = './spec/**/*_spec.rb' end - -task :default => :spec diff -Nru trocla-0.2.3/debian/rules trocla-0.3.0/debian/rules --- trocla-0.2.3/debian/rules 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/rules 2021-05-04 15:32:32.000000000 -0400 @@ -16,7 +16,3 @@ %: dh $@ --buildsystem=ruby --with ruby - -override_dh_auto_install: - dh_auto_install - rm debian/trocla/usr/lib/ruby/vendor_ruby/VERSION diff -Nru trocla-0.2.3/debian/upstream/metadata trocla-0.3.0/debian/upstream/metadata --- trocla-0.2.3/debian/upstream/metadata 1969-12-31 19:00:00.000000000 -0500 +++ trocla-0.3.0/debian/upstream/metadata 2021-05-04 15:32:32.000000000 -0400 @@ -0,0 +1,4 @@ +Bug-Database: https://github.com/duritong/trocla/issues +Bug-Submit: https://github.com/duritong/trocla/issues/new +Repository: https://github.com/duritong/trocla.git +Repository-Browse: https://github.com/duritong/trocla diff -Nru trocla-0.2.3/debian/watch trocla-0.3.0/debian/watch --- trocla-0.2.3/debian/watch 2016-03-01 16:05:19.000000000 -0500 +++ trocla-0.3.0/debian/watch 2021-05-04 15:32:32.000000000 -0400 @@ -1,2 +1,2 @@ version=3 -http://pkg-ruby-extras.alioth.debian.org/cgi-bin/gemwatch/trocla .*/trocla-(.*).tar.gz +https://pkg-ruby-extras.alioth.debian.org/cgi-bin/gemwatch/trocla .*/trocla-(.*).tar.gz diff -Nru trocla-0.2.3/ext/redhat/rubygem-trocla.spec trocla-0.3.0/ext/redhat/rubygem-trocla.spec --- trocla-0.2.3/ext/redhat/rubygem-trocla.spec 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/ext/redhat/rubygem-trocla.spec 2021-05-04 15:31:47.000000000 -0400 @@ -2,7 +2,7 @@ %global gem_name trocla Name: rubygem-%{gem_name} -Version: 0.2.2 +Version: 0.3.0 Release: 1%{?dist} Summary: Trocla a simple password generator and storage Group: Development/Languages @@ -74,9 +74,11 @@ cat <<EOF > %{buildroot}/%{_sysconfdir}/%{gem_name}rc.yaml --- -adapter: :YAML -adapter_options: - :file: '%{_sharedstatedir}/%{gem_name}/%{gem_name}_data.yaml' +store: :moneta +store_options: + adapter: :YAML + adapter_options: + :file: '%{_sharedstatedir}/%{gem_name}/%{gem_name}_data.yaml' EOF # Run the test suite diff -Nru trocla-0.2.3/Gemfile trocla-0.3.0/Gemfile --- trocla-0.2.3/Gemfile 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/Gemfile 2021-05-04 15:31:47.000000000 -0400 @@ -3,12 +3,22 @@ # Example: # gem "activesupport", ">= 2.3.5" +if RUBY_VERSION.to_f <= 2.2 + gem 'rack', '< 2.0' +end + +if RUBY_VERSION.to_f < 2.1 + gem 'nokogiri', '< 1.7' +end + if RUBY_VERSION.to_f > 1.8 gem "moneta" gem "highline" else gem "moneta", "~> 0.7.20" gem "highline", "~> 1.6.2" + gem 'rake', '< 11' + gem 'git', '< 1.3' end if defined?(RUBY_ENGINE) && (RUBY_ENGINE == 'jruby') @@ -22,7 +32,14 @@ if RUBY_VERSION.to_f > 1.8 gem "rspec" gem "rdoc" - gem "jeweler" + if RUBY_VERSION.to_f < 2.2 + gem 'jeweler', '< 2.2' + else + gem "jeweler" + end + if RUBY_VERSION.to_f < 2.0 + gem 'public_suffix', '~> 1.4.6' + end else gem "rspec", "~> 2.4" gem "rdoc", "~> 3.8" diff -Nru trocla-0.2.3/lib/trocla/formats/bcrypt.rb trocla-0.3.0/lib/trocla/formats/bcrypt.rb --- trocla-0.2.3/lib/trocla/formats/bcrypt.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla/formats/bcrypt.rb 2021-05-04 15:31:47.000000000 -0400 @@ -1,6 +1,7 @@ class Trocla::Formats::Bcrypt < Trocla::Formats::Base + expensive true require 'bcrypt' def format(plain_password,options={}) - BCrypt::Password.create(plain_password).to_s + BCrypt::Password.create(plain_password, :cost => options['cost']||BCrypt::Engine.cost).to_s end end diff -Nru trocla-0.2.3/lib/trocla/formats/x509.rb trocla-0.3.0/lib/trocla/formats/x509.rb --- trocla-0.2.3/lib/trocla/formats/x509.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla/formats/x509.rb 2021-05-04 15:31:47.000000000 -0400 @@ -1,5 +1,6 @@ require 'openssl' class Trocla::Formats::X509 < Trocla::Formats::Base + expensive true def format(plain_password,options={}) if plain_password.match(/-----BEGIN RSA PRIVATE KEY-----.*-----END RSA PRIVATE KEY-----.*-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----/m) diff -Nru trocla-0.2.3/lib/trocla/formats.rb trocla-0.3.0/lib/trocla/formats.rb --- trocla-0.2.3/lib/trocla/formats.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla/formats.rb 2021-05-04 15:31:47.000000000 -0400 @@ -8,6 +8,17 @@ def render(output,render_options={}) output end + def expensive? + self.class.expensive? + end + class << self + def expensive(is_expensive) + @expensive = is_expensive + end + def expensive? + @expensive == true + end + end end class << self diff -Nru trocla-0.2.3/lib/trocla/store.rb trocla-0.3.0/lib/trocla/store.rb --- trocla-0.2.3/lib/trocla/store.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla/store.rb 2021-05-04 15:31:47.000000000 -0400 @@ -6,6 +6,12 @@ @trocla = trocla end + # closes the store + # when called do whatever "closes" your + # store, e.g. close database connections. + def close + end + # should return value for key & format # returns nil if nothing or a nil value # was found. diff -Nru trocla-0.2.3/lib/trocla/stores/moneta.rb trocla-0.3.0/lib/trocla/stores/moneta.rb --- trocla-0.2.3/lib/trocla/stores/moneta.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla/stores/moneta.rb 2021-05-04 15:31:47.000000000 -0400 @@ -10,6 +10,10 @@ @moneta = Moneta.new(store_config['adapter'],adapter_options) end + def close + moneta.close + end + def get(key,format) moneta.fetch(key, {})[format] end diff -Nru trocla-0.2.3/lib/trocla/util.rb trocla-0.3.0/lib/trocla/util.rb --- trocla-0.2.3/lib/trocla/util.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla/util.rb 2021-05-04 15:31:47.000000000 -0400 @@ -24,6 +24,7 @@ 'numeric' => numeric, 'hexadecimal' => hexadecimal, 'consolesafe' => consolesafe, + 'typesafe' => typesafe, } h.each { |k, v| h[k] = v.uniq } end @@ -50,6 +51,9 @@ def numeric @numeric ||= ('0'..'9').to_a end + def typesafe + @typesafe ||= ('a'..'x').to_a - ['i'] - ['l'] + ('A'..'X').to_a - ['I'] - ['L'] + ('1'..'9').to_a + end def special_chars @special_chars ||= "*()&![]{}-".split(//) end diff -Nru trocla-0.2.3/lib/trocla.rb trocla-0.3.0/lib/trocla.rb --- trocla-0.2.3/lib/trocla.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/trocla.rb 2021-05-04 15:31:47.000000000 -0400 @@ -13,6 +13,17 @@ end end + def self.open(config_file=nil) + trocla = Trocla.new(config_file) + + if block_given? + yield trocla + trocla.close + else + trocla + end + end + def password(key,format,options={}) # respect a default profile, but let the # profiles win over the default options @@ -35,10 +46,15 @@ elsif !options['random'] && plain_pwd.nil? raise "Password must be present as plaintext if you don't want a random password" end - set_password(key, - format, - self.formats(format).format(plain_pwd,options), - options) + pwd = self.formats(format).format(plain_pwd,options) + # it's possible that meanwhile another thread/process was faster in + # formating the password. But we want todo that second lookup + # only for expensive formats + if self.formats(format).expensive? + get_password(key,format,options) || set_password(key, format, pwd, options) + else + set_password(key, format, pwd, options) + end end def get_password(key, format, options={}) @@ -78,6 +94,10 @@ @config ||= read_config end + def close + store.close + end + private def store @store ||= build_store diff -Nru trocla-0.2.3/lib/VERSION trocla-0.3.0/lib/VERSION --- trocla-0.2.3/lib/VERSION 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/lib/VERSION 2021-05-04 15:31:47.000000000 -0400 @@ -1,4 +1,4 @@ major:0 -minor:2 -patch:3 +minor:3 +patch:0 build: diff -Nru trocla-0.2.3/metadata.yml trocla-0.3.0/metadata.yml --- trocla-0.2.3/metadata.yml 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/metadata.yml 1969-12-31 19:00:00.000000000 -0500 @@ -1,188 +0,0 @@ ---- !ruby/object:Gem::Specification -name: trocla -version: !ruby/object:Gem::Version - version: 0.2.3 -platform: ruby -authors: -- mh -autorequire: -bindir: bin -cert_chain: [] -date: 2016-02-15 00:00:00.000000000 Z -dependencies: -- !ruby/object:Gem::Dependency - name: moneta - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :runtime - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: highline - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :runtime - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: bcrypt - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :runtime - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: rspec - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: rdoc - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: jeweler - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -- !ruby/object:Gem::Dependency - name: rspec-pending_for - requirement: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' - type: :development - prerelease: false - version_requirements: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -description: Trocla helps you to generate random passwords and to store them in various - formats (plain, MD5, bcrypt) for later retrival. -email: mh+tro...@immerda.ch -executables: -- trocla -extensions: [] -extra_rdoc_files: -- LICENSE.txt -- README.md -files: -- ".document" -- ".rspec" -- ".travis.yml" -- CHANGELOG.md -- Gemfile -- LICENSE.txt -- README.md -- Rakefile -- bin/trocla -- ext/redhat/rubygem-trocla.spec -- lib/VERSION -- lib/trocla.rb -- lib/trocla/default_config.yaml -- lib/trocla/encryptions.rb -- lib/trocla/encryptions/none.rb -- lib/trocla/encryptions/ssl.rb -- lib/trocla/formats.rb -- lib/trocla/formats/bcrypt.rb -- lib/trocla/formats/md5crypt.rb -- lib/trocla/formats/mysql.rb -- lib/trocla/formats/pgsql.rb -- lib/trocla/formats/plain.rb -- lib/trocla/formats/sha1.rb -- lib/trocla/formats/sha256crypt.rb -- lib/trocla/formats/sha512crypt.rb -- lib/trocla/formats/ssha.rb -- lib/trocla/formats/x509.rb -- lib/trocla/store.rb -- lib/trocla/stores.rb -- lib/trocla/stores/memory.rb -- lib/trocla/stores/moneta.rb -- lib/trocla/util.rb -- lib/trocla/version.rb -- spec/data/.keep -- spec/spec_helper.rb -- spec/trocla/encryptions/none_spec.rb -- spec/trocla/encryptions/ssl_spec.rb -- spec/trocla/formats/x509_spec.rb -- spec/trocla/store/memory_spec.rb -- spec/trocla/store/moneta_spec.rb -- spec/trocla/util_spec.rb -- spec/trocla_spec.rb -- trocla.gemspec -homepage: https://tech.immerda.ch/2011/12/trocla-get-hashed-passwords-out-of-puppet-manifests/ -licenses: -- GPLv3 -metadata: {} -post_install_message: -rdoc_options: [] -require_paths: -- lib -required_ruby_version: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -required_rubygems_version: !ruby/object:Gem::Requirement - requirements: - - - ">=" - - !ruby/object:Gem::Version - version: '0' -requirements: [] -rubyforge_project: -rubygems_version: 2.2.2 -signing_key: -specification_version: 4 -summary: Trocla a simple password generator and storage -test_files: [] diff -Nru trocla-0.2.3/README.md trocla-0.3.0/README.md --- trocla-0.2.3/README.md 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/README.md 2021-05-04 15:31:47.000000000 -0400 @@ -168,6 +168,11 @@ Password hashes for PostgreSQL servers. Requires the option `username` to be set to the username to which the password will be assigned. +### bcrypt + +You are able to tune the [cost factor of bcrypt](https://github.com/codahale/bcrypt-ruby#cost-factors) by passing the option `cost`. +Note: ruby bcrypt does not support a [cost > 31](https://github.com/codahale/bcrypt-ruby/blob/master/lib/bcrypt/password.rb#L45). + ### x509 This format takes a set of additional options. Required are: diff -Nru trocla-0.2.3/spec/spec_helper.rb trocla-0.3.0/spec/spec_helper.rb --- trocla-0.2.3/spec/spec_helper.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/spec/spec_helper.rb 2021-05-04 15:31:47.000000000 -0400 @@ -282,3 +282,9 @@ def remove_yaml_store File.unlink(trocla_yaml_file) end +class Trocla::Formats::Sleep < Trocla::Formats::Base + def format(plain_password,options={}) + sleep options['sleep'] ||= 0 + (options['sleep'] + 1 ).times.collect{ plain_password }.join(' ') + end +end diff -Nru trocla-0.2.3/spec/trocla/formats/x509_spec.rb trocla-0.3.0/spec/trocla/formats/x509_spec.rb --- trocla-0.2.3/spec/trocla/formats/x509_spec.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/spec/trocla/formats/x509_spec.rb 2021-05-04 15:31:47.000000000 -0400 @@ -242,12 +242,12 @@ expect(valid_cert.issuer.to_s).to eq(ca2.subject.to_s) expect((Date.parse(valid_cert.not_after.localtime.to_s) - Date.today).to_i).to eq(365) # workaround broken openssl - if %x{openssl version} =~ /1\.0\.[2-9]/ - expect(verify([@ca,ca2],valid_cert)).to be true - else + if Gem::Version.new(%x{openssl version}.split(' ')[1]) < Gem::Version.new('1.0.2') skip_for(:engine => 'ruby',:reason => 'NameConstraints verification is broken on older openssl versions https://rt.openssl.org/Ticket/Display.html?id=3562') do expect(verify([@ca,ca2],valid_cert)).to be true end + else + expect(verify([@ca,ca2],valid_cert)).to be true end false_cert_str = @trocla.password('myfalseexamplecert','x509', { @@ -311,7 +311,9 @@ # https://stackoverflow.com/questions/13747212/determine-key-size-from-public-key-pem-format expect(cert.public_key.n.num_bytes * 8).to eq(2048) expect(verify(@ca,cert)).to be true - expect(cert.extensions.find{|e| e.oid == 'subjectAltName' }.value).to eq('DNS:www.test, DNS:test, DNS:test1, DNS:test2, DNS:test3') + skip_for(:engine => 'jruby',:reason => 'subjectAltName represenation is broken in jruby-openssl -> https://github.com/jruby/jruby-openssl/pull/123') do + expect(cert.extensions.find{|e| e.oid == 'subjectAltName' }.value).to eq('DNS:www.test, DNS:test, DNS:test1, DNS:test2, DNS:test3') + end expect(cert.extensions.find{|e| e.oid == 'basicConstraints' }.value).to eq('CA:FALSE') ku = cert.extensions.find{|e| e.oid == 'keyUsage' }.value diff -Nru trocla-0.2.3/spec/trocla/util_spec.rb trocla-0.3.0/spec/trocla/util_spec.rb --- trocla-0.2.3/spec/trocla/util_spec.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/spec/trocla/util_spec.rb 2021-05-04 15:31:47.000000000 -0400 @@ -36,6 +36,14 @@ end end + describe :typesafe_generator do + 10.times.each do |i| + it "creates random typesafe password #{i}" do + expect(Trocla::Util.random_str(12, 'typesafe')).to match(/^[1-9a-hj-km-xA-HJ-KM-X]{12}$/) + end + end + end + describe :salt do 10.times.each do |i| it "contains only characters and numbers #{i}" do diff -Nru trocla-0.2.3/spec/trocla_spec.rb trocla-0.3.0/spec/trocla_spec.rb --- trocla-0.2.3/spec/trocla_spec.rb 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/spec/trocla_spec.rb 2021-05-04 15:31:47.000000000 -0400 @@ -4,144 +4,231 @@ before(:each) do expect_any_instance_of(Trocla).to receive(:read_config).and_return(test_config) - @trocla = Trocla.new end - - describe "password" do - it "generates random passwords by default" do - expect(@trocla.password('random1','plain')).not_to eq(@trocla.password('random2','plain')) + context 'in normal usage with' do + before(:each) do + @trocla = Trocla.new + @trocla.password('init','plain') end - it "generates passwords of length #{default_config['options']['length']}" do - expect(@trocla.password('random1','plain').length).to eq(default_config['options']['length']) - end + describe "password" do + it "generates random passwords by default" do + expect(@trocla.password('random1','plain')).not_to eq(@trocla.password('random2','plain')) + end + + it "generates passwords of length #{default_config['options']['length']}" do + expect(@trocla.password('random1','plain').length).to eq(default_config['options']['length']) + end + + Trocla::Formats.all.each do |format| + describe "#{format} password format" do + it "retursn a password hashed in the #{format} format" do + expect(@trocla.password('some_test',format,format_options[format])).not_to be_empty + end - Trocla::Formats.all.each do |format| - describe "#{format} password format" do - it "retursn a password hashed in the #{format} format" do - expect(@trocla.password('some_test',format,format_options[format])).not_to be_empty + it "returns the same hashed for the #{format} format on multiple invocations" do + expect(round1=@trocla.password('some_test',format,format_options[format])).not_to be_empty + expect(@trocla.password('some_test',format,format_options[format])).to eq(round1) + end + + it "also stores the plain password by default" do + pwd = @trocla.password('some_test','plain') + expect(pwd).not_to be_empty + expect(pwd.length).to eq(16) + end + end + end + + Trocla::Formats.all.reject{|f| f == 'plain' }.each do |format| + it "raises an exception if not a random password is asked but plain password is not present for format #{format}" do + expect{@trocla.password('not_random',format, 'random' => false)}.to raise_error(/Password must be present as plaintext/) end + end - it "returns the same hashed for the #{format} format on multiple invocations" do - expect(round1=@trocla.password('some_test',format,format_options[format])).not_to be_empty - expect(@trocla.password('some_test',format,format_options[format])).to eq(round1) + describe 'with profiles' do + it 'raises an exception on unknown profile' do + expect{@trocla.password('no profile known','plain', + 'profiles' => 'unknown_profile') }.to raise_error(/No such profile unknown_profile defined/) end - it "also stores the plain password by default" do - pwd = @trocla.password('some_test','plain') + it 'takes a profile and merge its options' do + pwd = @trocla.password('some_test','plain', 'profiles' => 'rootpw') + expect(pwd).not_to be_empty + expect(pwd.length).to eq(32) + expect(pwd).to_not match(/[={}\[\]\?%\*()&!]+/) + end + + it 'is possible to combine profiles but first profile wins' do + pwd = @trocla.password('some_test1','plain', 'profiles' => ['rootpw','login']) + expect(pwd).not_to be_empty + expect(pwd.length).to eq(32) + expect(pwd).not_to match(/[={}\[\]\?%\*()&!]+/) + end + it 'is possible to combine profiles but first profile wins 2' do + pwd = @trocla.password('some_test2','plain', 'profiles' => ['login','mysql']) expect(pwd).not_to be_empty expect(pwd.length).to eq(16) + expect(pwd).not_to match(/[={}\[\]\?%\*()&!]+/) + end + it 'is possible to combine profiles but first profile wins 3' do + pwd = @trocla.password('some_test3','plain', 'profiles' => ['mysql','login']) + expect(pwd).not_to be_empty + expect(pwd.length).to eq(32) + expect(pwd).to match(/[+%\/@=\?_.,:]+/) end end end - Trocla::Formats.all.reject{|f| f == 'plain' }.each do |format| - it "raises an exception if not a random password is asked but plain password is not present for format #{format}" do - expect{@trocla.password('not_random',format, 'random' => false)}.to raise_error(/Password must be present as plaintext/) - end - end + describe "set_password" do + it "resets hashed passwords on a new plain password" do + expect(@trocla.password('set_test','mysql')).not_to be_empty + expect(@trocla.get_password('set_test','mysql')).not_to be_nil + expect(old_plain=@trocla.password('set_test','mysql')).not_to be_empty - describe 'with profiles' do - it 'raises an exception on unknown profile' do - expect{@trocla.password('no profile known','plain', - 'profiles' => 'unknown_profile') }.to raise_error(/No such profile unknown_profile defined/) - end - - it 'takes a profile and merge its options' do - pwd = @trocla.password('some_test','plain', 'profiles' => 'rootpw') - expect(pwd).not_to be_empty - expect(pwd.length).to eq(32) - expect(pwd).to_not match(/[={}\[\]\?%\*()&!]+/) - end - - it 'is possible to combine profiles but first profile wins' do - pwd = @trocla.password('some_test','plain', 'profiles' => ['rootpw','login']) - expect(pwd).not_to be_empty - expect(pwd.length).to eq(32) - expect(pwd).not_to match(/[={}\[\]\?%\*()&!]+/) - end - it 'is possible to combine profiles but first profile wins 2' do - pwd = @trocla.password('some_test','plain', 'profiles' => ['login','mysql']) - expect(pwd).not_to be_empty - expect(pwd.length).to eq(16) - expect(pwd).not_to match(/[={}\[\]\?%\*()&!]+/) - end - it 'is possible to combine profiles but first profile wins 3' do - pwd = @trocla.password('some_test','plain', 'profiles' => ['mysql','login']) - expect(pwd).not_to be_empty - expect(pwd.length).to eq(32) - expect(pwd).to match(/[+%\/@=\?_.,:]+/) + expect(@trocla.set_password('set_test','plain','foobar')).not_to eq(old_plain) + expect(@trocla.get_password('set_test','mysql')).to be_nil end - end - end - describe "set_password" do - it "resets hashed passwords on a new plain password" do - expect(@trocla.password('set_test','mysql')).not_to be_empty - expect(@trocla.get_password('set_test','mysql')).not_to be_nil - expect(old_plain=@trocla.password('set_test','mysql')).not_to be_empty - - expect(@trocla.set_password('set_test','plain','foobar')).not_to eq(old_plain) - expect(@trocla.get_password('set_test','mysql')).to be_nil - end - - it "otherwise updates only the hash" do - expect(mysql = @trocla.password('set_test2','mysql')).not_to be_empty - expect(md5crypt = @trocla.password('set_test2','md5crypt')).not_to be_empty - expect(plain = @trocla.get_password('set_test2','plain')).not_to be_empty - - expect(new_mysql = @trocla.set_password('set_test2','mysql','foo')).not_to eql(mysql) - expect(@trocla.get_password('set_test2','mysql')).to eq(new_mysql) - expect(@trocla.get_password('set_test2','md5crypt')).to eq(md5crypt) - expect(@trocla.get_password('set_test2','plain')).to eq(plain) + it "otherwise updates only the hash" do + expect(mysql = @trocla.password('set_test2','mysql')).not_to be_empty + expect(md5crypt = @trocla.password('set_test2','md5crypt')).not_to be_empty + expect(plain = @trocla.get_password('set_test2','plain')).not_to be_empty + + expect(new_mysql = @trocla.set_password('set_test2','mysql','foo')).not_to eql(mysql) + expect(@trocla.get_password('set_test2','mysql')).to eq(new_mysql) + expect(@trocla.get_password('set_test2','md5crypt')).to eq(md5crypt) + expect(@trocla.get_password('set_test2','plain')).to eq(plain) + end end - end - describe "reset_password" do - it "resets a password" do - plain1 = @trocla.password('reset_pwd','plain') - plain2 = @trocla.reset_password('reset_pwd','plain') + describe "reset_password" do + it "resets a password" do + plain1 = @trocla.password('reset_pwd','plain') + plain2 = @trocla.reset_password('reset_pwd','plain') - expect(plain1).not_to eq(plain2) - end + expect(plain1).not_to eq(plain2) + end - it "does not reset other formats" do - expect(mysql = @trocla.password('reset_pwd2','mysql')).not_to be_empty - expect(md5crypt1 = @trocla.password('reset_pwd2','md5crypt')).not_to be_empty + it "does not reset other formats" do + expect(mysql = @trocla.password('reset_pwd2','mysql')).not_to be_empty + expect(md5crypt1 = @trocla.password('reset_pwd2','md5crypt')).not_to be_empty - expect(md5crypt2 = @trocla.reset_password('reset_pwd2','md5crypt')).not_to be_empty - expect(md5crypt2).not_to eq(md5crypt1) + expect(md5crypt2 = @trocla.reset_password('reset_pwd2','md5crypt')).not_to be_empty + expect(md5crypt2).not_to eq(md5crypt1) - expect(@trocla.get_password('reset_pwd2','mysql')).to eq(mysql) + expect(@trocla.get_password('reset_pwd2','mysql')).to eq(mysql) + end end - end - describe "delete_password" do - it "deletes all passwords if no format is given" do - expect(@trocla.password('delete_test1','mysql')).not_to be_nil - expect(@trocla.get_password('delete_test1','plain')).not_to be_nil + describe "delete_password" do + it "deletes all passwords if no format is given" do + expect(@trocla.password('delete_test1','mysql')).not_to be_nil + expect(@trocla.get_password('delete_test1','plain')).not_to be_nil - @trocla.delete_password('delete_test1') - expect(@trocla.get_password('delete_test1','plain')).to be_nil - expect(@trocla.get_password('delete_test1','mysql')).to be_nil - end + @trocla.delete_password('delete_test1') + expect(@trocla.get_password('delete_test1','plain')).to be_nil + expect(@trocla.get_password('delete_test1','mysql')).to be_nil + end + + it "deletes only a given format" do + expect(@trocla.password('delete_test2','mysql')).not_to be_nil + expect(@trocla.get_password('delete_test2','plain')).not_to be_nil - it "deletes only a given format" do - expect(@trocla.password('delete_test2','mysql')).not_to be_nil - expect(@trocla.get_password('delete_test2','plain')).not_to be_nil + @trocla.delete_password('delete_test2','plain') + expect(@trocla.get_password('delete_test2','plain')).to be_nil + expect(@trocla.get_password('delete_test2','mysql')).not_to be_nil + end + + it "deletes only a given non-plain format" do + expect(@trocla.password('delete_test3','mysql')).not_to be_nil + expect(@trocla.get_password('delete_test3','plain')).not_to be_nil - @trocla.delete_password('delete_test2','plain') - expect(@trocla.get_password('delete_test2','plain')).to be_nil - expect(@trocla.get_password('delete_test2','mysql')).not_to be_nil + @trocla.delete_password('delete_test3','mysql') + expect(@trocla.get_password('delete_test3','mysql')).to be_nil + expect(@trocla.get_password('delete_test3','plain')).not_to be_nil + end end - it "deletes only a given non-plain format" do - expect(@trocla.password('delete_test3','mysql')).not_to be_nil - expect(@trocla.get_password('delete_test3','plain')).not_to be_nil + context 'concurrent access' do + context 'on expensive flagged formats' do + before(:each) do + expect(Trocla::Formats).to receive(:[]).with('sleep').at_least(:once).and_return(Trocla::Formats::Sleep) + expect(Trocla::Formats::Sleep).to receive(:expensive?).at_least(:once).and_return(true) + expect(Trocla::Formats).to receive(:available?).with('sleep').at_least(:once).and_return(true) + end + it 'should not overwrite a value if it takes longer' do + t1 = Thread.new{ @trocla.password('threadpwd','sleep','sleep' => 4) } + t2 = Thread.new{ @trocla.password('threadpwd','sleep','sleep' => 1) } + pwd1 = t1.value + pwd2 = t2.value + real_value = @trocla.password('threadpwd','sleep') + # as t2 finished first this should win + expect(pwd1).to eql(pwd2) + expect(real_value).to eql(pwd1) + expect(real_value).to eql(pwd2) + end + end + context 'on inexpensive flagged formats' do + before(:each) do + expect(Trocla::Formats).to receive(:[]).with('sleep').at_least(:once).and_return(Trocla::Formats::Sleep) + expect(Trocla::Formats::Sleep).to receive(:expensive?).at_least(:once).and_return(false) + expect(Trocla::Formats).to receive(:available?).with('sleep').at_least(:once).and_return(true) + end + it 'should not overwrite a value if it takes longer' do + t1 = Thread.new{ @trocla.password('threadpwd_inexp','sleep','sleep' => 4) } + t2 = Thread.new{ @trocla.password('threadpwd_inexp','sleep','sleep' => 1) } + pwd1 = t1.value + pwd2 = t2.value + real_value = @trocla.password('threadpwd_inexp','sleep') + # as t2 finished first but the format is inexpensive it gets overwritten + expect(pwd1).not_to eql(pwd2) + expect(real_value).to eql(pwd1) + expect(real_value).not_to eql(pwd2) + end + end + context 'real world example' do + it 'should store the quicker one' do + t1 = Thread.new{ @trocla.password('threadpwd_real','bcrypt','cost' => 17) } + t2 = Thread.new{ @trocla.password('threadpwd_real','bcrypt') } + pwd1 = t1.value + pwd2 = t2.value + real_value = @trocla.password('threadpwd_real','bcrypt') + # t2 should still win but both should be the same + expect(pwd1).to eql(pwd2) + expect(real_value).to eql(pwd1) + expect(real_value).to eql(pwd2) + end + it 'should store the quicker one test 2' do + t1 = Thread.new{ @trocla.password('my_shiny_selfsigned_ca', 'x509', { + 'CN' => 'This is my self-signed certificate', + 'become_ca' => false, + }) } + t2 = Thread.new{ @trocla.password('my_shiny_selfsigned_ca', 'x509', { + 'CN' => 'This is my self-signed certificate', + 'become_ca' => false, + }) } + cert1 = t1.value + cert2 = t2.value + real_value = @trocla.password('my_shiny_selfsigned_ca','x509') + # t2 should still win but both should be the same + expect(cert1).to eql(cert2) + expect(real_value).to eql(cert1) + expect(real_value).to eql(cert2) + end + end + end - @trocla.delete_password('delete_test3','mysql') - expect(@trocla.get_password('delete_test3','mysql')).to be_nil - expect(@trocla.get_password('delete_test3','plain')).not_to be_nil + end + context 'with .open' do + it 'closes the connection with a block' do + expect_any_instance_of(Trocla::Stores::Memory).to receive(:close) + Trocla.open{|t| + t.password('plain_open','plain') + } + end + it 'keeps the connection without a block' do + expect_any_instance_of(Trocla::Stores::Memory).not_to receive(:close) + Trocla.open.password('plain_open','plain') end end diff -Nru trocla-0.2.3/.travis.yml trocla-0.3.0/.travis.yml --- trocla-0.2.3/.travis.yml 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/.travis.yml 2021-05-04 15:31:47.000000000 -0400 @@ -1,10 +1,11 @@ language: ruby sudo: false rvm: + - jruby - jruby-18mode - jruby-19mode + - 2.4.0 - 2.2.0 - - 2.1.0 - 2.0.0 - 1.9.3 - 1.8.7 diff -Nru trocla-0.2.3/trocla.gemspec trocla-0.3.0/trocla.gemspec --- trocla-0.2.3/trocla.gemspec 2016-03-01 15:40:25.000000000 -0500 +++ trocla-0.3.0/trocla.gemspec 2021-05-04 15:31:47.000000000 -0400 @@ -2,19 +2,19 @@ # DO NOT EDIT THIS FILE DIRECTLY # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' # -*- encoding: utf-8 -*- -# stub: trocla 0.2.3 ruby lib +# stub: trocla 0.3.0 ruby lib Gem::Specification.new do |s| - s.name = "trocla" - s.version = "0.2.3" + s.name = "trocla".freeze + s.version = "0.3.0" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib"] - s.authors = ["mh"] - s.date = "2016-02-15" - s.description = "Trocla helps you to generate random passwords and to store them in various formats (plain, MD5, bcrypt) for later retrival." - s.email = "mh+tro...@immerda.ch" - s.executables = ["trocla"] + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["mh".freeze] + s.date = "2017-08-04" + s.description = "Trocla helps you to generate random passwords and to store them in various formats (plain, MD5, bcrypt) for later retrival.".freeze + s.email = "mh+tro...@immerda.ch".freeze + s.executables = ["trocla".freeze] s.extra_rdoc_files = [ "LICENSE.txt", "README.md" @@ -64,39 +64,39 @@ "spec/trocla_spec.rb", "trocla.gemspec" ] - s.homepage = "https://tech.immerda.ch/2011/12/trocla-get-hashed-passwords-out-of-puppet-manifests/" - s.licenses = ["GPLv3"] - s.rubygems_version = "2.2.2" - s.summary = "Trocla a simple password generator and storage" + s.homepage = "https://tech.immerda.ch/2011/12/trocla-get-hashed-passwords-out-of-puppet-manifests/".freeze + s.licenses = ["GPLv3".freeze] + s.rubygems_version = "2.6.11".freeze + s.summary = "Trocla a simple password generator and storage".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q<moneta>, [">= 0"]) - s.add_runtime_dependency(%q<highline>, [">= 0"]) - s.add_runtime_dependency(%q<bcrypt>, [">= 0"]) - s.add_development_dependency(%q<rspec>, [">= 0"]) - s.add_development_dependency(%q<rdoc>, [">= 0"]) - s.add_development_dependency(%q<jeweler>, [">= 0"]) - s.add_development_dependency(%q<rspec-pending_for>, [">= 0"]) + s.add_runtime_dependency(%q<moneta>.freeze, [">= 0"]) + s.add_runtime_dependency(%q<highline>.freeze, [">= 0"]) + s.add_runtime_dependency(%q<bcrypt>.freeze, [">= 0"]) + s.add_development_dependency(%q<rspec>.freeze, [">= 0"]) + s.add_development_dependency(%q<rdoc>.freeze, [">= 0"]) + s.add_development_dependency(%q<jeweler>.freeze, [">= 0"]) + s.add_development_dependency(%q<rspec-pending_for>.freeze, [">= 0"]) else - s.add_dependency(%q<moneta>, [">= 0"]) - s.add_dependency(%q<highline>, [">= 0"]) - s.add_dependency(%q<bcrypt>, [">= 0"]) - s.add_dependency(%q<rspec>, [">= 0"]) - s.add_dependency(%q<rdoc>, [">= 0"]) - s.add_dependency(%q<jeweler>, [">= 0"]) - s.add_dependency(%q<rspec-pending_for>, [">= 0"]) + s.add_dependency(%q<moneta>.freeze, [">= 0"]) + s.add_dependency(%q<highline>.freeze, [">= 0"]) + s.add_dependency(%q<bcrypt>.freeze, [">= 0"]) + s.add_dependency(%q<rspec>.freeze, [">= 0"]) + s.add_dependency(%q<rdoc>.freeze, [">= 0"]) + s.add_dependency(%q<jeweler>.freeze, [">= 0"]) + s.add_dependency(%q<rspec-pending_for>.freeze, [">= 0"]) end else - s.add_dependency(%q<moneta>, [">= 0"]) - s.add_dependency(%q<highline>, [">= 0"]) - s.add_dependency(%q<bcrypt>, [">= 0"]) - s.add_dependency(%q<rspec>, [">= 0"]) - s.add_dependency(%q<rdoc>, [">= 0"]) - s.add_dependency(%q<jeweler>, [">= 0"]) - s.add_dependency(%q<rspec-pending_for>, [">= 0"]) + s.add_dependency(%q<moneta>.freeze, [">= 0"]) + s.add_dependency(%q<highline>.freeze, [">= 0"]) + s.add_dependency(%q<bcrypt>.freeze, [">= 0"]) + s.add_dependency(%q<rspec>.freeze, [">= 0"]) + s.add_dependency(%q<rdoc>.freeze, [">= 0"]) + s.add_dependency(%q<jeweler>.freeze, [">= 0"]) + s.add_dependency(%q<rspec-pending_for>.freeze, [">= 0"]) end end
signature.asc
Description: PGP signature