commit 52d3e7fe4e169241cc6fe92d587da09cf1ff6d49
parent 99caeccbbcddaf33b405338bae624ba0f7bb733c
Author: Hamish Downer <dmishd@gmail.com>
Date: Thu, 10 Feb 2011 00:27:01 +0000
Better gpg error checking.
The crypto initialize code now checks for a number of common reasons
for GPG not working, all related to the gpg-agent side of things. It
will then give a reasonably friendly error message, helping diagnose
why GPG is not working for you.
In particular it will check whether the environment variable is set,
whether the environment variable points to a file, and whether that
file is a socket.
Diffstat:
1 file changed, 43 insertions(+), 13 deletions(-)
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
@@ -42,19 +42,53 @@ EOS
def initialize
@mutex = Mutex.new
+ @not_working_reason = nil
+
# test if the gpgme gem is available
- @gpgme_present = true
- begin
- GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
- rescue NameError, GPGME::Error
- @gpgme_present = false
+ @gpgme_present =
+ begin
+ begin
+ GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
+ true
+ rescue GPGME::Error
+ false
+ end
+ rescue NameError
+ false
+ end
+
+ unless @gpgme_present
+ @not_working_reason = 'gpgme gem not present'
+ return
+ end
+
+ # check gpg agent stuff
+ if ENV['GPG_AGENT_INFO'].nil?
+ @not_working_reason = "Environment variable 'GPG_AGENT_INFO' not set"
+ return
+ end
+
+ gpg_agent_socket_file = ENV['GPG_AGENT_INFO'].split(':')[0]
+ unless file.exist?(gpg_agent_socket_file)
+ @not_working_reason = "gpg-agent socket file #{gpg_agent_socket_file} does not exist"
+ return
+ end
+
+ s = File.stat(gpg_agent_socket_file)
+ unless s.socket?
+ @not_working_reason = "gpg-agent socket file #{gpg_agent_socket_file} is not a socket"
+ return
+ end
+
+ if (bin = `which gpg2`.chomp) =~ /\S/
+ GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
end
end
def have_crypto?; @gpgme_present end
def sign from, to, payload
- return unknown_status(cant_find_gpgme) unless @gpgme_present
+ return unknown_status([@not_working_reason]) unless @not_working_reason.nil?
gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
gpg_opts.merge!(gen_sign_user_opts(from))
@@ -85,7 +119,7 @@ EOS
end
def encrypt from, to, payload, sign=false
- return unknown_status(cant_find_gpgme) unless @gpgme_present
+ return unknown_status([@not_working_reason]) unless @not_working_reason.nil?
gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
if sign
@@ -173,7 +207,7 @@ EOS
end
def verify payload, signature, detached=true # both RubyMail::Message objects
- return unknown_status(cant_find_gpgme) unless @gpgme_present
+ return unknown_status([@not_working_reason]) unless @not_working_reason.nil?
gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP}
gpg_opts = HookManager.run("gpg-options",
@@ -197,7 +231,7 @@ EOS
## returns decrypted_message, status, desc, lines
def decrypt payload, armor=false # a RubyMail::Message object
- return unknown_status(cant_find_gpgme) unless @gpgme_present
+ return unknown_status([@not_working_reason]) unless @not_working_reason.nil?
gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP}
gpg_opts = HookManager.run("gpg-options",
@@ -267,10 +301,6 @@ private
Chunk::CryptoNotice.new :unknown, "Unable to determine validity of cryptographic signature", lines
end
- def cant_find_gpgme
- ["Can't find gpgme gem."]
- end
-
## here's where we munge rmail output into the format that signed/encrypted
## PGP/GPG messages should be
def format_payload payload