hiera-eyaml-gpg_ruby 0.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5b28ae68e2c44ec9d0affeb33fbd80c20b4c8c91
4
+ data.tar.gz: f51e6e955b0945a892b16a02c380208de56565a3
5
+ SHA512:
6
+ metadata.gz: b604dca4f51feb1e09d9bff6a4fd8f611eb49945bd64438103d89f607c927e8ffa056b08ab50a0e7e838e1099e75739f285a0226fb8096c1d8b862f1a11b2c44
7
+ data.tar.gz: 6e9f289d7b9c55b61ee644e527a7ebee2afe6e0c1143e400511c5e106fda6c70a9359f966cb5039a944da3164e0cc0636c2e0397e51615e5a1095d2feaafe924
@@ -0,0 +1,7 @@
1
+ .idea
2
+ *.iml
3
+ *.gradle
4
+ keys/*.pem
5
+ pkg/
6
+ tmp/
7
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org/'
2
+
3
+ gem 'hiera-eyaml', ">=1.3.8"
4
+ gem 'gpgme', ">=2.0.0"
5
+
6
+ group :development do
7
+ gem "aruba"
8
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Simon Hildrew
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,72 @@
1
+ hiera-eyaml-gpg
2
+ ===============
3
+
4
+ GPG encryption backend for the [hiera-eyaml](https://github.com/TomPoulton/hiera-eyaml) module.
5
+
6
+ Motivation
7
+ ----------
8
+
9
+ The default PKCS#7 encryption scheme used by hiera-eyaml is perfect if only simple
10
+ encryption and decryption is needed.
11
+
12
+ However, if you are in a sizable team it helps to encrypt and decrypt data with multiple
13
+ keys. This means that each team member can hold their own private key and so can the puppetmaster.
14
+ Equally, each puppet master can have their own key if desired and when you need to rotate
15
+ keys for either users or puppet masters, re-encrypting your files and changing the key everywhere
16
+ does not need to be done in lockstep.
17
+
18
+ Requirements
19
+ ------------
20
+
21
+ You'll need a working GPG setup with your own keypair and a public keyring containing any other
22
+ keys that you want to work
23
+
24
+ To get started, install the hiera-eyaml-gpg gem.
25
+
26
+ $ gem install hiera-eyaml-gpg
27
+
28
+ If you haven't already installed it, this requires and will install the hiera-eyaml gem, which you
29
+ should probably acquint yourself with at https://github.com/TomPoulton/hiera-eyaml.
30
+
31
+ Note that in order to install the gpgme gem you'll need to have the ruby development package installed
32
+ for your distribution.
33
+
34
+ How to use
35
+ ----------
36
+
37
+ ### Encrypting and editing encrypted data
38
+
39
+ Once installed you can create encrypted hiera-eyaml blocks that are encrypted using GPG.
40
+
41
+ $ eyaml encrypt -n gpg -s "A secret string to encrypt" --gpg-recipients bob@example.com,hiera@example.com
42
+
43
+ If you do not have a web of trust (i.e. you normally use --always-trust for gpg signing) then you'll need
44
+ to use the `--gpg-always-trust` option on the command line.
45
+
46
+ It gets pretty dull to keep on remembering which recipients you should use, so you can put them in a file
47
+ and specify that instead.
48
+
49
+ $ eyaml encrypt -n gpg -s "A secret string to encrypt" --gpg-recipients-file hiera-eyaml-gpg.recipients
50
+
51
+ In fact, when editing a file on disk and neither of the --gpg-recipient options are provided it will
52
+ automatically look for a `hiera-eyaml-gpg.recipients` file in the same directory as the file being edited
53
+ (or any parent in the tree). The first file discovered will be used allowing different parts of a hiera
54
+ tree to have different recipients if so desired.
55
+
56
+ Use `eyaml --help` for more details or look at the hiera-eyaml docs.
57
+
58
+ ### Configuring hiera
59
+
60
+ Assuming you have a working `hiera` and `hiera-eyaml` then the only option you need to add is to
61
+ configure `:gpg_gnupghome:` in your hiera.yaml (under the `:eyaml:` section). This should be the
62
+ directory that contains the keyring etc for the user that can to decrypt the hiera data. Please note
63
+ that the private GPG key must not have a passphrase.
64
+
65
+ Authors
66
+ -------
67
+
68
+ - Simon Hildrew - Initial code
69
+ - Geoff Meakins - Created hiera-eyaml plugin framework that made this possible
70
+
71
+ ### Contributors
72
+ - Walt Javins - Bug fixes
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hiera/backend/eyaml/encryptors/gpg/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "hiera-eyaml-gpg_ruby"
8
+ gem.version = Hiera::Backend::Eyaml::Encryptors::Gpg::VERSION
9
+ gem.description = "GPG encryptor for use with hiera-eyaml, in pure Ruby"
10
+ gem.summary = "Encryption plugin for hiera-eyaml backend for Hiera, in pure Ruby"
11
+ gem.author = "Raphaël Pinson"
12
+ gem.license = "MIT"
13
+
14
+ gem.homepage = "http://github.com/raphink/hiera-eyaml-gpg_ruby"
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency('hiera-eyaml', '>=1.3.8')
21
+ gem.add_dependency('ruby_gpg', '>=0.3.0')
22
+ end
@@ -0,0 +1,177 @@
1
+ require 'gpgme'
2
+ require 'base64'
3
+ require 'pathname'
4
+ require 'hiera/backend/eyaml/encryptor'
5
+ require 'hiera/backend/eyaml/utils'
6
+ require 'hiera/backend/eyaml/options'
7
+
8
+ class Hiera
9
+ module Backend
10
+ module Eyaml
11
+ module Encryptors
12
+
13
+ class Gpg < Encryptor
14
+
15
+ self.tag = "GPG"
16
+
17
+ self.options = {
18
+ :gnupghome => { :desc => "Location of your GNUPGHOME directory",
19
+ :type => :string,
20
+ :default => "#{ENV[["HOME", "HOMEPATH"].detect { |h| ENV[h] != nil }]}/.gnupg" },
21
+ :always_trust => { :desc => "Assume that used keys are fully trusted",
22
+ :type => :boolean,
23
+ :default => false },
24
+ :recipients => { :desc => "List of recipients (comma separated)",
25
+ :type => :string },
26
+ :recipients_file => { :desc => "File containing a list of recipients (one on each line)",
27
+ :type => :string }
28
+ }
29
+
30
+ @@passphrase_cache = Hash.new
31
+
32
+ def self.passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
33
+ begin
34
+ system('stty -echo')
35
+
36
+ unless @@passphrase_cache.has_key?(uid_hint)
37
+ @@passphrase_cache[uid_hint] = ask("Enter passphrase for #{uid_hint}: ") { |q| q.echo = '' }
38
+ $stderr.puts
39
+ end
40
+ passphrase = @@passphrase_cache[uid_hint]
41
+
42
+ io = IO.for_fd(fd, 'w')
43
+ io.puts(passphrase)
44
+ io.flush
45
+ ensure
46
+ (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
47
+ system('stty echo')
48
+ end
49
+ end
50
+
51
+ def self.find_recipients
52
+ recipient_option = self.option :recipients
53
+ recipients = if !recipient_option.nil?
54
+ debug("Using --recipients option")
55
+ recipient_option.split(",")
56
+ else
57
+ recipient_file_option = self.option :recipients_file
58
+ recipient_file = if !recipient_file_option.nil?
59
+ debug("Using --recipients-file option")
60
+ Pathname.new(recipient_file_option)
61
+ else
62
+ debug("Searching for any hiera-eyaml-gpg.recipients files in path")
63
+ # if we are editing a file, look for a hiera-eyaml-gpg.recipients file
64
+ filename = case Eyaml::Options[:source]
65
+ when :file
66
+ Eyaml::Options[:file]
67
+ when :eyaml
68
+ Eyaml::Options[:eyaml]
69
+ else
70
+ nil
71
+ end
72
+
73
+ if filename.nil?
74
+ nil
75
+ else
76
+ path = Pathname.new(filename).realpath.dirname
77
+ selected_file = nil
78
+ path.descend{|path| path
79
+ potential_file = path.join('hiera-eyaml-gpg.recipients')
80
+ selected_file = potential_file if potential_file.exist?
81
+ }
82
+ debug("Using file at #{selected_file}")
83
+ selected_file
84
+ end
85
+ end
86
+
87
+ unless recipient_file.nil?
88
+ recipient_file.readlines.map{ |line| line.strip }
89
+ else
90
+ []
91
+ end
92
+ end
93
+ end
94
+
95
+ def self.encrypt plaintext
96
+ gnupghome = self.option :gnupghome
97
+ GPGME::Engine.home_dir = gnupghome
98
+ debug("GNUPGHOME is #{gnupghome}")
99
+
100
+ ctx = GPGME::Ctx.new
101
+
102
+ recipients = self.find_recipients
103
+ debug("Recipents are #{recipients}")
104
+
105
+ raise RecoverableError, 'No recipients provided, don\'t know who to encrypt to' if recipients.empty?
106
+
107
+ keys = recipients.map {|r|
108
+ key_to_use = ctx.keys(r).first
109
+ if key_to_use.nil?
110
+ raise RecoverableError, "No key found on keyring for #{r}"
111
+ end
112
+ key_to_use
113
+ }
114
+ debug("Keys: #{keys}")
115
+
116
+ always_trust = self.option(:always_trust)
117
+ unless always_trust
118
+ # check validity of recipients (this is possibly naive, but better than the unhelpful
119
+ # error that it would spit out otherwise)
120
+ keys.each do |key|
121
+ unless key.primary_uid.validity >= GPGME::VALIDITY_FULL
122
+ raise RecoverableError, "Key #{key.sha} (#{key.email}) not trusted (if key trust is established by another means then specify always-trust)"
123
+ end
124
+ end
125
+ end
126
+
127
+ data = GPGME::Data.from_str(plaintext)
128
+ crypto = GPGME::Crypto.new(:always_trust => always_trust)
129
+
130
+ ciphertext = crypto.encrypt(data, :recipients => keys)
131
+ ciphertext.seek 0
132
+ ciphertext.read
133
+ end
134
+
135
+ def self.decrypt ciphertext
136
+ gnupghome = self.option :gnupghome
137
+ GPGME::Engine.home_dir = gnupghome
138
+ debug("GNUPGHOME is #{gnupghome}")
139
+
140
+ ctx = if hiera?
141
+ GPGME::Ctx.new
142
+ else
143
+ GPGME::Ctx.new(:passphrase_callback => method(:passfunc))
144
+ end
145
+
146
+ if !ctx.keys.empty?
147
+ raw = GPGME::Data.new(ciphertext)
148
+ txt = GPGME::Data.new
149
+
150
+ begin
151
+ txt = ctx.decrypt(raw)
152
+ rescue GPGME::Error::DecryptFailed => e
153
+ warn("Fatal: Failed to decrypt ciphertext (check settings and that you are a recipient)")
154
+ raise e
155
+ rescue Exception => e
156
+ warn("Warning: General exception decrypting GPG file")
157
+ raise e
158
+ end
159
+
160
+ txt.seek 0
161
+ txt.read
162
+ else
163
+ warn("No usable keys found in #{gnupghome}. Check :gpg_gnupghome value in hiera.yaml is correct")
164
+ raise ArgumentError, "No usable keys found in #{gnupghome}. Check :gpg_gnupghome value in hiera.yaml is correct"
165
+ end
166
+ end
167
+
168
+ def self.create_keys
169
+ STDERR.puts "The GPG encryptor does not support creation of keys, use the GPG command lines tools instead"
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,3 @@
1
+ require 'hiera/backend/eyaml/encryptors/gpg'
2
+
3
+ Hiera::Backend::Eyaml::Encryptors::Gpg.register
@@ -0,0 +1,11 @@
1
+ class Hiera
2
+ module Backend
3
+ module Eyaml
4
+ module Encryptors
5
+ module Gpg
6
+ VERSION = "0.4"
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ gem uninstall hiera-eyaml-gpg
4
+ rake build
5
+ gem install pkg/hiera-eyaml-gpg
6
+ eyaml -v
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hiera-eyaml-gpg_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.4'
5
+ platform: ruby
6
+ authors:
7
+ - Raphaël Pinson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: hiera-eyaml
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.8
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.8
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby_gpg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.0
41
+ description: GPG encryptor for use with hiera-eyaml, in pure Ruby
42
+ email:
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - ".gitignore"
48
+ - Gemfile
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - hiera-eyaml-gpg_ruby.gemspec
53
+ - lib/hiera/backend/eyaml/encryptors/gpg.rb
54
+ - lib/hiera/backend/eyaml/encryptors/gpg/eyaml_init.rb
55
+ - lib/hiera/backend/eyaml/encryptors/gpg/version.rb
56
+ - tools/regem.sh
57
+ homepage: http://github.com/raphink/hiera-eyaml-gpg_ruby
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.2.2
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Encryption plugin for hiera-eyaml backend for Hiera, in pure Ruby
81
+ test_files: []