Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 66 additions & 17 deletions lib/puppet/provider/gpgkey/gpgme.rb
Original file line number Diff line number Diff line change
@@ -1,36 +1,85 @@
Puppet::Type.type(:gpgkey).provide(:gpgme) do
# This provider uses the new API of the gpgme-2.0.0 gem.
require 'gpgme'

def exists?
! GPGME::Key.find(:secret, keyname()).empty?
run_as_user do
Process.exit!(GPGME::Key.find(:secret, keyname()).empty? ? 1 : 0)
end == 0
end

def create
ctx = GPGME::Ctx.new
keydata = "<GnupgKeyParms format=\"internal\">\n"
keydata += "Key-Type: " [email protected](:keytype)+"\n"
keydata += "Key-Length: " [email protected](:keylength)+"\n"
keydata += "Subkey-Type: " [email protected](:subkeytype)+"\n"
keydata += "Subkey-Length: " [email protected](:subkeylength)+"\n"
keydata += "Name-Real: " [email protected](:name)+"\n"
keydata += "Name-Comment: " +keyname()+"\n"
keydata += "Name-Email: " [email protected](:email)+"\n"
keydata += "Expire-Date: " [email protected](:expire)+"\n"
keydata += "Passphrase: " [email protected](:password)+"\n"
keydata += "</GnupgKeyParms>\n"

ctx.genkey(keydata, nil, nil)
run_as_user do
GPGME::Ctx.new do |ctx|
keydata = "<GnupgKeyParms format=\"internal\">\n"
keydata += "Key-Type: " [email protected](:keytype)+"\n"
keydata += "Key-Length: " [email protected](:keylength)+"\n"
keydata += "Subkey-Type: " [email protected](:subkeytype)+"\n"
keydata += "Subkey-Length: " [email protected](:subkeylength)+"\n"
keydata += "Name-Real: " [email protected](:name)+"\n"
keydata += "Name-Comment: " +keyname()+"\n"
keydata += "Name-Email: " [email protected](:email)+"\n"
keydata += "Expire-Date: " [email protected](:expire)+"\n"
# This parameter requires a value when present. Default is to
# not use a passphrase.
unless @resource.value(:password).empty?
keydata += "Passphrase: " [email protected](:password)+"\n"
end
keydata += "</GnupgKeyParms>\n"

ctx.genkey(keydata, nil, nil)
end
end
end

def destroy
GPGME::Key.find(:secret, keyname()).each do |key|
key.delete!(true)
run_as_user do
GPGME::Key.find(:secret, keyname()).each do |key|
key.delete!(true)
end
end
end

private

def keyname
keyname = 'puppet#' + @resource.value(:name) + '#'
return keyname
end

def run_as_user(&block)
if (pid = Process.fork).nil?
Puppet::Util::SUIDManager.change_privileges(@resource.value(:user), nil, true)
with_env(&block)
Process.exit!
else
Process.waitpid(pid)
$?.exitstatus
end
end

def with_env(&block)
env_vars = %w{HOME GNUPGHOME}
old_env = env_vars.map { |var| ENV[var] }

begin
ENV['HOME'] = Etc.getpwuid(Process.uid).dir

if @resource.value(:gnupghome)
ENV['GNUPGHOME'] = @resource.value(:gnupghome)
else
ENV.delete('GNUPGHOME')
end

Dir.chdir(ENV['HOME']) do
yield
end
ensure
old_env.each_with_index { |val, i|
var = env_vars[i]
val.nil? ? ENV.delete(var) : (ENV[var] = val)
}
end
end

end
19 changes: 19 additions & 0 deletions lib/puppet/type/gpgkey.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,23 @@
defaultto true
end

newparam(:user) do
desc <<-EOT
The user account in which the key should be managed.
The resource will automatically depend on this user.
EOT
end

newparam(:gnupghome) do
desc <<-EOT
The GnuPG data directory in which the key should be managed.
If this is not set, GnuPG selects the directory by itself.
EOT
end

# Autorequire the owner of the ~/.gnupg directory.
autorequire(:user) do
self[:user]
end

end
2 changes: 1 addition & 1 deletion manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
}

package { 'gpgme':
ensure => 'instaled',
ensure => 'installed',
provider => $gpgme_provider,
require => Package['gnupg']
}
Expand Down