passw3rd 0.0.11 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -0
- data/lib/passw3rd/key_loader.rb +3 -2
- data/lib/passw3rd/password_service.rb +52 -28
- data/lib/passw3rd/version.rb +1 -1
- data/spec/config_spec.rb +3 -0
- data/spec/password_service_spec.rb +14 -0
- data/spec/spec_helper.rb +1 -0
- data/test/password_service_test.rb +19 -1
- metadata +5 -2
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.1.0 / 2011-10-31
|
2
|
+
|
3
|
+
Finally some real life support
|
4
|
+
* Defaults to aes-256 for regulatory compliance (Thanks Edward Bonver)
|
5
|
+
* loads URIs, so password files can live anywhere (Thanks Ben Duong)
|
6
|
+
* Internals: code cleanup (Thanks @xternal), guard + test::unit + rspec love, better configuration options (thanks again @xternal)
|
7
|
+
|
1
8
|
=== 0.0.11 / 2011-10-12
|
2
9
|
|
3
10
|
Keys/ivs were being written as arrays, broke openssl command line compatibility:
|
data/lib/passw3rd/key_loader.rb
CHANGED
@@ -7,7 +7,7 @@ module Passw3rd
|
|
7
7
|
|
8
8
|
def self.load(path=nil)
|
9
9
|
if path.nil?
|
10
|
-
path =
|
10
|
+
path = ::Passw3rd::PasswordService.key_file_dir
|
11
11
|
end
|
12
12
|
|
13
13
|
begin
|
@@ -29,7 +29,8 @@ module Passw3rd
|
|
29
29
|
path = ENV['HOME']
|
30
30
|
end
|
31
31
|
|
32
|
-
|
32
|
+
# d'oh!
|
33
|
+
cipher = OpenSSL::Cipher::Cipher.new(::Passw3rd::PasswordService.cipher_name)
|
33
34
|
iv = cipher.random_iv
|
34
35
|
key = cipher.random_key
|
35
36
|
|
@@ -1,37 +1,46 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
1
3
|
module Passw3rd
|
2
4
|
class PasswordService
|
3
|
-
|
4
|
-
|
5
|
+
class << self
|
6
|
+
attr_writer :password_file_dir
|
7
|
+
def password_file_dir
|
8
|
+
@password_file_dir || ENV.fetch("HOME")
|
9
|
+
end
|
5
10
|
|
6
|
-
|
7
|
-
|
11
|
+
attr_writer :key_file_dir
|
12
|
+
def key_file_dir
|
13
|
+
@key_file_dir || ENV.fetch("HOME")
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_writer :cipher_name
|
17
|
+
def cipher_name
|
18
|
+
@cipher_name || 'aes-256-cbc'
|
19
|
+
end
|
8
20
|
end
|
9
21
|
|
10
|
-
def self.
|
11
|
-
|
12
|
-
end
|
22
|
+
def self.configure(&block)
|
23
|
+
instance_eval &block
|
24
|
+
end
|
13
25
|
|
14
|
-
def self.get_password (password_file, key_path=
|
15
|
-
|
16
|
-
|
26
|
+
def self.get_password (password_file, key_path = key_file_dir)
|
27
|
+
uri = _parse_uri(password_file)
|
28
|
+
encoded_password = Base64.decode64(open(uri.to_s) { |f| f.read })
|
29
|
+
decrypt(encoded_password, key_path)
|
17
30
|
end
|
18
31
|
|
19
|
-
def self.write_password_file(password, output_path, key_path =
|
20
|
-
enc_password =
|
32
|
+
def self.write_password_file(password, output_path, key_path = key_file_dir)
|
33
|
+
enc_password = encrypt(password, key_path)
|
21
34
|
base64pw = Base64.encode64(enc_password)
|
22
|
-
path = File.join(
|
23
|
-
|
35
|
+
path = File.join(password_file_dir, output_path)
|
36
|
+
open(path, 'w') { |f| f.write base64pw }
|
24
37
|
path
|
25
38
|
end
|
26
39
|
|
27
|
-
def self.encrypt(password, key_path =
|
28
|
-
raise "password cannot be blank" if password.empty?
|
40
|
+
def self.encrypt(password, key_path = key_file_dir)
|
41
|
+
raise ArgumentError, "password cannot be blank" if password.to_s.empty?
|
29
42
|
|
30
|
-
|
31
|
-
cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
|
32
|
-
cipher.encrypt
|
33
|
-
cipher.key = pair.key
|
34
|
-
cipher.iv = pair.iv
|
43
|
+
cipher = cipher_setup(:encrypt, key_path)
|
35
44
|
begin
|
36
45
|
e = cipher.update(password)
|
37
46
|
e << cipher.final
|
@@ -41,19 +50,34 @@ module Passw3rd
|
|
41
50
|
end
|
42
51
|
end
|
43
52
|
|
44
|
-
def self.decrypt(cipher_text, key_path =
|
45
|
-
|
46
|
-
cipher = OpenSSL::Cipher::Cipher.new('aes-128-cbc')
|
47
|
-
cipher.decrypt
|
48
|
-
cipher.key = pair.key
|
49
|
-
cipher.iv = pair.iv
|
53
|
+
def self.decrypt(cipher_text, key_path = key_file_dir)
|
54
|
+
cipher = cipher_setup(:decrypt, key_path)
|
50
55
|
begin
|
51
56
|
d = cipher.update(cipher_text)
|
52
57
|
d << cipher.final
|
53
58
|
rescue OpenSSL::Cipher::CipherError => err
|
54
|
-
puts "
|
59
|
+
puts "Couldn't decrypt password. Are you using the right keys?"
|
55
60
|
raise err
|
56
61
|
end
|
57
62
|
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def self.cipher_setup(method, key_path)
|
67
|
+
pair = KeyLoader.load(key_path)
|
68
|
+
cipher = OpenSSL::Cipher::Cipher.new(cipher_name)
|
69
|
+
cipher.send(method)
|
70
|
+
cipher.key = pair.key
|
71
|
+
cipher.iv = pair.iv
|
72
|
+
cipher
|
73
|
+
end
|
74
|
+
|
75
|
+
def self._parse_uri password_file
|
76
|
+
unless (password_file =~ URI::regexp(['ftp', 'http', 'https', 'file'])).nil?
|
77
|
+
URI.parse(password_file)
|
78
|
+
else
|
79
|
+
File.join(password_file_dir, password_file)
|
80
|
+
end
|
81
|
+
end
|
58
82
|
end
|
59
83
|
end
|
data/lib/passw3rd/version.rb
CHANGED
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ::Passw3rd::PasswordService do
|
4
|
+
describe "#_parse_uri" do
|
5
|
+
it "detects uris" do
|
6
|
+
::Passw3rd::PasswordService._parse_uri("http://example.com").should be_is_a URI::HTTP
|
7
|
+
end
|
8
|
+
|
9
|
+
it "falls back to a file path" do
|
10
|
+
URI.should_not_receive(:parse)
|
11
|
+
::Passw3rd::PasswordService._parse_uri("/some/file/some/where/over/the/rainbow").should be_is_a String
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'passw3rd'
|
@@ -11,6 +11,7 @@ class PasswordServiceTest < Test::Unit::TestCase
|
|
11
11
|
|
12
12
|
::Passw3rd::KeyLoader.create_key_iv_file(Dir.tmpdir)
|
13
13
|
::Passw3rd::PasswordService.key_file_dir = Dir.tmpdir
|
14
|
+
::Passw3rd::PasswordService.cipher_name = 'aes-256-cbc'
|
14
15
|
end
|
15
16
|
|
16
17
|
def test_enc_dec
|
@@ -20,6 +21,14 @@ class PasswordServiceTest < Test::Unit::TestCase
|
|
20
21
|
assert_equal(@random_string, dec)
|
21
22
|
end
|
22
23
|
|
24
|
+
def test_enc_raise_on_blank_password
|
25
|
+
assert_raise(ArgumentError) { ::Passw3rd::PasswordService.encrypt("") }
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_enc_raise_on_nil_password
|
29
|
+
assert_raise(ArgumentError) { ::Passw3rd::PasswordService.encrypt(nil) }
|
30
|
+
end
|
31
|
+
|
23
32
|
def test_set_and_get_password
|
24
33
|
password_file = ::Passw3rd::PasswordService.write_password_file(@random_string, "test")
|
25
34
|
decrypted = Passw3rd::PasswordService.get_password("test")
|
@@ -33,6 +42,15 @@ class PasswordServiceTest < Test::Unit::TestCase
|
|
33
42
|
decrypted = Passw3rd::PasswordService.get_password("test2")
|
34
43
|
assert_equal(@random_string, decrypted)
|
35
44
|
end
|
45
|
+
|
46
|
+
def test_configure_with_block
|
47
|
+
Passw3rd::PasswordService.configure do |c|
|
48
|
+
c.password_file_dir = "/tmp/"
|
49
|
+
c.cipher_name = "aes-256-cbc"
|
50
|
+
end
|
51
|
+
assert_equal(Passw3rd::PasswordService.password_file_dir, "/tmp/")
|
52
|
+
assert_equal(Passw3rd::PasswordService.cipher_name, "aes-256-cbc")
|
53
|
+
end
|
36
54
|
|
37
55
|
def test_gen_key
|
38
56
|
enc = ::Passw3rd::PasswordService.encrypt(@random_string)
|
@@ -44,4 +62,4 @@ class PasswordServiceTest < Test::Unit::TestCase
|
|
44
62
|
def sudorandumb
|
45
63
|
Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by{rand}.join)
|
46
64
|
end
|
47
|
-
end
|
65
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passw3rd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-10-
|
12
|
+
date: 2011-10-31 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description: Generate a key/iv file, generate passwords, and store encrypted files
|
15
15
|
in source control, keep the key/iv safe!
|
@@ -31,6 +31,9 @@ files:
|
|
31
31
|
- lib/passw3rd.rb
|
32
32
|
- bin/passw3rd
|
33
33
|
- test/password_service_test.rb
|
34
|
+
- spec/config_spec.rb
|
35
|
+
- spec/password_service_spec.rb
|
36
|
+
- spec/spec_helper.rb
|
34
37
|
homepage: https://github.com/oreoshake/passw3rd
|
35
38
|
licenses: []
|
36
39
|
post_install_message:
|