ansible-vault 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c64c35022f30a4f3c587291beec7db13bbde45c8
4
- data.tar.gz: a67022fa1b3d67df377f9eb1fdf926f428d67235
3
+ metadata.gz: 1561653af6b72805f9ee3b499283f31ebe7707b1
4
+ data.tar.gz: 5825d44806493f47c5d65c5b7861e90a498288cb
5
5
  SHA512:
6
- metadata.gz: d143eb2573573c5f83adf5e373f440c2d5207d2cc4933c13f1d58bcdd8a1a4f2cd60aa6f0babbafe60fc9487bde28207007a600cc25c686353f0ffcfb2b9b2b5
7
- data.tar.gz: 696b412c876e520bba00d1884db687c5ad63f118cd23adfd624681e06095534c988ebdc422a07b6f503156b7298a4efb9fb183e2c8b2cefc62d6d203c424c8a2
6
+ metadata.gz: a7b7efd82f58ffd4787e01a0abb89be74b61d5442d7a8a754f0fc4217915dc4b3d00879b5c8658b5e466fedcdec5473275d6e4bb0300dfd6759974a1343b1ae8
7
+ data.tar.gz: 08aab745f2914dcde6eda24c5f713d6c7577512c8758248d93cdd0a95ae89126bfa96aa9e2a47ff25c00cdcb952abd0d4c2559207627734fea9153ed4bccd046
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## v 0.2.0
4
+ * Added checks for nil/blank passwords (#4)
5
+ * Added the ability to check if a file is encrypted (#3)
6
+
7
+ ## v 0.1.0 Initial Release
8
+ * Implemented Read and write commands
data/README.md CHANGED
@@ -68,8 +68,18 @@ release a new version, update the version number in `version.rb`, and then run
68
68
  git commits and tags, and push the `.gem` file to
69
69
  [rubygems.org](https://rubygems.org).
70
70
 
71
+
71
72
  ## Contributing
72
73
 
73
74
  Bug reports and pull requests are welcome on GitHub at
74
- https://github.com/tpickett66/ansible-vault-rb.
75
+ https://github.com/tpickett66/ansible-vault-rb. This project is intended to be
76
+ a safe, welcoming space for collaboration, and contributors are expected to
77
+ adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
78
+ conduct.
79
+
80
+
81
+ ## License
82
+
83
+ The gem is available as open source under the terms of the
84
+ [MIT License](http://opensource.org/licenses/MIT).
75
85
 
@@ -10,34 +10,56 @@ require 'ansible/vault/version'
10
10
  module Ansible
11
11
  # The top level class for interacting with Vault files.
12
12
  class Vault
13
- # Read and decrypt the plaintext contents of a vault
13
+ # The standard header for Ansible's current vault format
14
+ FILE_HEADER = "$ANSIBLE_VAULT;1.1;AES256".freeze
15
+
16
+ # Indicate if the file at the supplied path appeard to be encrypted by
17
+ # Ansible Vault
18
+ #
19
+ # @param path [String, Pathname]
20
+ def self.encrypted?(path)
21
+ FileReader.new(path.to_s).encrypted?
22
+ end
23
+
24
+ # Read and decrypt, if necessary, the contents of a vault
25
+ #
26
+ # If the file does not appear to be encrypted the file is simply read.
14
27
  #
15
- # @param path [String] The path to the file to read
28
+ # @param path [String, Pathname] The path to the file to read
16
29
  # @param password [String] The password for the file
30
+ # @param options [Hash] Additional options, see {#initialize} for details
17
31
  # @return [String] The plaintext contents of the vault, this is marked for
18
32
  # zeroing before the GC reaps the object. Any data extracted/parsed from
19
33
  # this string should be similarly wiped from memory when no longer used.
20
- def self.read(path:, password:)
21
- new(path: path, password: password).read
34
+ def self.read(path:, password:, **options)
35
+ new(path: path, password: password, **options).read
22
36
  end
23
37
 
24
38
  # Encrypt plaintext using the supplied and write it to the specified location
25
39
  #
26
- # @param path [String] The path to the file to write, truncated before writing
40
+ # @param path [String, Pathname] The path to the file to write, truncated
41
+ # before writing
27
42
  # @param password [String] The password for the file
28
43
  # @param plaintext [String] The secrets to be protected
44
+ # @param options [Hash] Additional options, see {#initialize} for details
29
45
  # @return [File] The closed file handle the vault was written to
30
- def self.write(path:, password:, plaintext:)
31
- new(path: path, password: password, plaintext: plaintext).write
46
+ def self.write(path:, password:, plaintext:, **options)
47
+ new(path: path, password: password, plaintext: plaintext, **options).write
32
48
  end
33
49
 
34
50
  # Build a new Vault
35
51
  #
36
- # @param path [String] The path to the file to read
52
+ # @param path [String, Pathname] The path to the file to read
37
53
  # @param password [String] The password for the file
38
- def initialize(path:, password:, plaintext: :none)
54
+ # @param options [Hash] Additional options
55
+ # @param plaintext [String] The plaintext of the file to be written when
56
+ # encrypting
57
+ # @option options [Boolean] :allow_blank_password Allow nil and empty string
58
+ # passwords, defaults to false.
59
+ def initialize(path:, password:, plaintext: :none, **options)
60
+ @path = path.to_s
39
61
  @path = path
40
- @password = password.shred_later
62
+ @password = validate_password(password, options).shred_later
41
63
  @plaintext = plaintext
42
64
  @plaintext.shred_later if String === @plaintext
43
65
  end
@@ -64,13 +86,27 @@ module Ansible
64
86
 
65
87
  # Extract the plaintext from a previously written vault file
66
88
  #
89
+ # If the file does not appear to be encrypted the raw contents will be
90
+ # returned.
91
+ #
67
92
  # @return [String] The plaintext contents of the vault, this is marked for
68
93
  # zeroing before the GC reaps the object. Any data extracted/parsed from
69
94
  # this string should be similarly wiped from memory when no longer used.
70
95
  def read
71
96
  file = FileReader.new(@path)
97
+ return File.read(@path) unless file.encrypted?
72
98
  decryptor = Decryptor.new(password: @password, file: file)
73
99
  decryptor.plaintext
74
100
  end
101
+
102
+ private
103
+
104
+ def validate_password(password, options)
105
+ if !options[:allow_blank_password] && (password.nil? || password.strip.empty?)
106
+ raise BlankPassword, 'A nil or empty string password was supplied!' \
107
+ 'If this is expected set the allow_blank_password option.'
108
+ end
109
+ password or ''
110
+ end
75
111
  end
76
112
  end
@@ -3,5 +3,6 @@ module Ansible
3
3
  class Error < StandardError; end
4
4
  class MissingSalt < Error; end
5
5
  class HMACMismatch < Error; end
6
+ class BlankPassword < Error; end
6
7
  end
7
8
  end
@@ -46,10 +46,23 @@ module Ansible
46
46
  @salt
47
47
  end
48
48
 
49
+ # Indicates if the file is in the encrypted format or not
50
+ #
51
+ # @return [Boolean]
52
+ def encrypted?
53
+ decode_body unless defined?(@salt)
54
+ # The header not matching is a dead giveaway that the file isn't what
55
+ # we're expecting. That, however, probably isn't enough so we'll check
56
+ # the HMAC for presence and length since it's very unlikely that
57
+ # decoding the file body will result in multiple chunks AND the second
58
+ # one being the correct length for a SHA256 HMAC.
59
+ @header == FILE_HEADER && !@hmac.nil? && @hmac.bytesize == 64
60
+ end
61
+
49
62
  private
50
63
 
51
64
  def decode_body
52
- salt, @hmac, ciphertext = BinASCII.unhexlify(@body).split("\n")
65
+ salt, @hmac, ciphertext = BinASCII.unhexlify(@body).split("\n", 3)
53
66
  @ciphertext = BinASCII.unhexlify(ciphertext)
54
67
  @salt = BinASCII.unhexlify(salt)
55
68
  end
@@ -16,9 +16,6 @@ module Ansible
16
16
  attr_reader :path
17
17
  attr_accessor :ciphertext, :hmac, :salt
18
18
 
19
- # The standard header for Ansible's current vault format
20
- HEADER = "$ANSIBLE_VAULT;1.1;AES256\n".freeze
21
-
22
19
  # Construct a new FileWriter
23
20
  #
24
21
  # @param [String] path The path to write the file out to.
@@ -31,7 +28,7 @@ module Ansible
31
28
  # @return [File] The closed file handle used to write the data out.
32
29
  def write
33
30
  File.open(path, 'w') { |file|
34
- file.write(HEADER)
31
+ file.write(FILE_HEADER + "\n")
35
32
  file.write(encoded_body)
36
33
  }
37
34
  end
@@ -1,5 +1,5 @@
1
1
  module Ansible
2
2
  class Vault
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ansible-vault
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Pickett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-13 00:00:00.000000000 Z
11
+ date: 2016-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oroku_saki
@@ -119,6 +119,7 @@ files:
119
119
  - ".gitignore"
120
120
  - ".rspec"
121
121
  - ".travis.yml"
122
+ - CHANGELOG.md
122
123
  - CODE_OF_CONDUCT.md
123
124
  - Gemfile
124
125
  - Guardfile