sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit a8238ea2979bf9be7284bfd3b1fee3af3f27c303
parent 98fdfb3b2114145537ee10fe9b060074d34d2a8d
Author: Hamish Downer <dmishd@gmail.com>
Date:   Thu, 10 Feb 2011 00:47:58 +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:
M lib/sup/crypto.rb | 37 ++++++++++++++++++++++++++++---------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
@@ -42,6 +42,8 @@ EOS
   def initialize
     @mutex = Mutex.new
 
+    @not_working_reason = nil
+
     # test if the gpgme gem is available
     @gpgme_present =
       begin
@@ -55,7 +57,28 @@ EOS
         false
       end
 
-    return unless @gpgme_present
+    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
@@ -65,7 +88,7 @@ EOS
   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))
@@ -96,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
@@ -184,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",
@@ -208,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",
@@ -278,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