hiera-eyaml-gpg 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -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.4"
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.
data/README.md ADDED
@@ -0,0 +1,16 @@
1
+ hiera-eyaml-gpg
2
+ ===============
3
+
4
+ GPG encryprion 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.
data/Rakefile ADDED
@@ -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"
8
+ gem.version = Hiera::Backend::Eyaml::Encryptors::Gpg::VERSION
9
+ gem.description = "GPG encryptor for use with hiera-eyaml"
10
+ gem.summary = "Encryption plugin for hiera-eyaml backend for Hiera"
11
+ gem.author = "Simon Hildrew"
12
+ gem.license = "MIT"
13
+
14
+ gem.homepage = "http://github.com/sihil/hiera-eyaml-gpg"
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.4')
21
+ gem.add_dependency('gpgme', '>=2.0.0')
22
+ 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.1"
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,161 @@
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
+ def self.passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
31
+ begin
32
+ system('stty -echo')
33
+ passphrase = ask("Enter passphrase for #{uid_hint}: ") { |q| q.echo = '*' }
34
+ io = IO.for_fd(fd, 'w')
35
+ io.puts(passphrase)
36
+ io.flush
37
+ ensure
38
+ (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
39
+ system('stty echo')
40
+ end
41
+ $stderr.puts
42
+ end
43
+
44
+ def self.find_recipients
45
+ recipient_option = self.option :recipients
46
+ recipients = if !recipient_option.nil?
47
+ debug("Using --recipients option")
48
+ recipient_option.split(",")
49
+ else
50
+ recipient_file_option = self.option :recipients_file
51
+ recipient_file = if !recipient_file_option.nil?
52
+ debug("Using --recipients-file option")
53
+ Pathname.new(recipient_file_option)
54
+ else
55
+ debug("Searching for any hiera-eyaml-gpg.recipents files in path")
56
+ # if we are editing a file, look for a hiera-eyaml-gpg.recipients file
57
+ filename = case Eyaml::Options[:source]
58
+ when :file
59
+ Eyaml::Options[:file]
60
+ when :eyaml
61
+ Eyaml::Options[:eyaml]
62
+ else
63
+ nil
64
+ end
65
+
66
+ if filename.nil?
67
+ nil
68
+ else
69
+ path = Pathname.new(filename).realpath.dirname
70
+ selected_file = nil
71
+ path.descend{|path| path
72
+ potential_file = path.join('hiera-eyaml-gpg.recipients')
73
+ selected_file = potential_file if potential_file.exist?
74
+ }
75
+ debug("Using file at #{selected_file}")
76
+ selected_file
77
+ end
78
+ end
79
+
80
+ unless recipient_file.nil?
81
+ recipient_file.readlines.map{ |line| line.strip }
82
+ else
83
+ []
84
+ end
85
+ end
86
+ end
87
+
88
+ def self.encrypt plaintext
89
+ ENV["GNUPGHOME"] = self.option :gnupghome
90
+ debug("GNUPGHOME is #{ENV['GNUPGHOME']}")
91
+
92
+ ctx = GPGME::Ctx.new
93
+
94
+ recipients = self.find_recipients
95
+ debug("Recipents are #{recipients}")
96
+
97
+ raise ArgumentError, 'No recipients provided, don\'t know who to encrypt to' if recipients.empty?
98
+
99
+ keys = recipients.map {|r| ctx.keys(r).first }
100
+ debug("Keys: #{keys}")
101
+
102
+ always_trust = self.option(:always_trust)
103
+ unless always_trust
104
+ # check validity of recipients (this is possibly naive, but better than the unhelpful
105
+ # error that it would spit out otherwise)
106
+ keys.each do |key|
107
+ unless key.primary_uid.validity >= GPGME::VALIDITY_FULL
108
+ raise StandardError, "Key #{key.sha} (#{key.email}) not trusted (if key trust is established by another means then specify always-trust)"
109
+ end
110
+ end
111
+ end
112
+
113
+ data = GPGME::Data.from_str(plaintext)
114
+ crypto = GPGME::Crypto.new(:always_trust => always_trust)
115
+
116
+ ciphertext = crypto.encrypt(data, :recipients => keys)
117
+ ciphertext.seek 0
118
+ ciphertext.read
119
+ end
120
+
121
+ def self.decrypt ciphertext
122
+ ENV["GNUPGHOME"] = self.option :gnupghome
123
+ debug("GNUPGHOME is #{ENV['GNUPGHOME']}")
124
+
125
+ ctx = if hiera?
126
+ GPGME::Ctx.new
127
+ else
128
+ GPGME::Ctx.new(:passphrase_callback => method(:passfunc))
129
+ end
130
+
131
+ if !ctx.keys.empty?
132
+ raw = GPGME::Data.new(ciphertext)
133
+ txt = GPGME::Data.new
134
+
135
+ begin
136
+ txt = ctx.decrypt(raw)
137
+ rescue GPGME::Error::DecryptFailed => e
138
+ warn("Fatal: Failed to decrypt ciphertext (check settings and that you are a recipient)")
139
+ raise e
140
+ rescue Exception => e
141
+ warn("Warning: General exception decrypting GPG file")
142
+ raise e
143
+ end
144
+
145
+ txt.seek 0
146
+ txt.read
147
+ else
148
+ warn("No usable keys found in #{ENV['GNUPGHOME']}. Check :gpgpghome value in hiera.yaml is correct")
149
+ end
150
+ end
151
+
152
+ def self.create_keys
153
+ STDERR.puts "The GPG encryptor does not support creation of keys, use the GPG command lines tools instead"
154
+ end
155
+
156
+ end
157
+
158
+ end
159
+ end
160
+ end
161
+ end
data/tools/regem.sh ADDED
@@ -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,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hiera-eyaml-gpg
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Simon Hildrew
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-09-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hiera-eyaml
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.3.4
30
+ - !ruby/object:Gem::Dependency
31
+ name: gpgme
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 2.0.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 2.0.0
46
+ description: GPG encryptor for use with hiera-eyaml
47
+ email:
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - .gitignore
53
+ - Gemfile
54
+ - LICENSE
55
+ - README.md
56
+ - Rakefile
57
+ - hiera-eyaml-gpg.gemspec
58
+ - lib/hiera/backend/eyaml/encryptors/gpg.rb
59
+ - lib/hiera/backend/eyaml/encryptors/gpg/eyaml_init.rb
60
+ - lib/hiera/backend/eyaml/encryptors/gpg/version.rb
61
+ - tools/regem.sh
62
+ homepage: http://github.com/sihil/hiera-eyaml-gpg
63
+ licenses:
64
+ - MIT
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.23
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Encryption plugin for hiera-eyaml backend for Hiera
87
+ test_files: []