Subject: [sup-devel] [PATCH] Adding a gpgkey option

From: Hamish D <[email-masked]>
Date: Sun, 10 Oct 2010 17:25:18 +0100

>From the commit message:

    Added a gpgkey option to the account settings

    This allows the user to specify the gpg key used. In addition, if
    gpgkey is not set, and there is only one email address defined, then
    sup will not pass any id to gpg, so gpg will use its default key.
    Only if gpgkey is not set and there are multiple email addresses
    will sup use the old behaviour of defining the key to use by
    passing gpg the from email address.

This has been requested before:
http://rubyforge.org/pipermail/sup-devel/2009-November/000029.html

I've given it some basic testing (using the gpg-args hook to view the
arguments) and it appears to work as I intend it to in all 3 cases I
mention in the comment. I'm not a massively experienced ruby hacker,
so any feedback or improvements appreciated.

Hamish
From 6b3d7101756e703a52ec7e2a8606b6ee583895c9 Mon Sep 17 00:00:00 2001
From: Hamish Downer <[email-masked]>
Date: Sun, 10 Oct 2010 17:18:41 +0100
Subject: [PATCH] Added a gpgkey option to the account settings

This allows the user to specify the gpg key used. In addition, if
gpgkey is not set, and there is only one email address defined, then
sup will not pass any id to gpg, so gpg will use its default key.
Only if gpgkey is not set and there are multiple email addresses
will sup use the old behaviour of defining the key to use by
passing gpg the from email address.
---
 lib/sup.rb         |    3 ++-
 lib/sup/account.rb |    5 +++--
 lib/sup/crypto.rb  |   23 +++++++++++++++++++++--
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/lib/sup.rb b/lib/sup.rb
index abd3bce..0e051be 100644
--- a/lib/sup.rb
+++ b/lib/sup.rb
@@ -261,7 +261,8 @@ EOS
             :email => email,
             :alternates => [],
             :sendmail => "/usr/sbin/sendmail -oem -ti",
-            :signature => File.join(ENV["HOME"], ".signature")
+            :signature => File.join(ENV["HOME"], ".signature"),
+            :gpgkey => ""
           }
         },
         :editor => ENV["EDITOR"] || "/usr/bin/vim -f -c 'setlocal spell spelllang=en_us' -c 'set filetype=mail'",
diff --git a/lib/sup/account.rb b/lib/sup/account.rb
index f932f4c..1718d94 100644
--- a/lib/sup/account.rb
+++ b/lib/sup/account.rb
@@ -1,7 +1,7 @@
 module Redwood
 
 class Account < Person
-  attr_accessor :sendmail, :signature
+  attr_accessor :sendmail, :signature, :gpgkey
 
   def initialize h
     raise ArgumentError, "no name for account" unless h[:name]
@@ -9,6 +9,7 @@ class Account < Person
     super h[:name], h[:email]
     @sendmail = h[:sendmail]
     @signature = h[:signature]
+    @gpgkey = h[:gpgkey]
   end
 
   # Default sendmail command for bouncing mail,
@@ -46,7 +47,7 @@ class AccountManager
   def add_account hash, default=false
     raise ArgumentError, "no email specified for account" unless hash[:email]
     unless default
-      [:name, :sendmail, :signature].each { |k| hash[k] ||= @default_account.send(k) }
+      [:name, :sendmail, :signature, :gpgkey].each { |k| hash[k] ||= @default_account.send(k) }
     end
     hash[:alternates] ||= []
 
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
index 2bd5350..19983d2 100644
--- a/lib/sup/crypto.rb
+++ b/lib/sup/crypto.rb
@@ -45,7 +45,8 @@ EOS
 
     sig_fn = Tempfile.new "redwood.signature"; sig_fn.close
 
-    message = run_gpg "--output #{sig_fn.path} --yes --armor --detach-sign --textmode --digest-algo sha256 --local-user '#{from}' #{payload_fn.path}", :interactive => true
+    sign_user_opts = gen_sign_user_opts from
+    message = run_gpg "--output #{sig_fn.path} --yes --armor --detach-sign --textmode --digest-algo sha256 #{sign_user_opts} #{payload_fn.path}", :interactive => true
     unless $?.success?
       info "Error while running gpg: #{message}"
       raise Error, "GPG command failed. See log for details."
@@ -68,7 +69,8 @@ EOS
     encrypted_fn = Tempfile.new "redwood.encrypted"; encrypted_fn.close
 
     recipient_opts = (to + [ from ] ).map { |r| "--recipient '<#{r}>'" }.join(" ")
-    sign_opts = sign ? "--sign --local-user '#{from}'" : ""
+    sign_opts = ""
+    sign_opts = "--sign --digest-algo sha256 " + gen_sign_user_opts(from) if sign
     message = run_gpg "--output #{encrypted_fn.path} --yes --armor --encrypt --textmode #{sign_opts} #{recipient_opts} #{payload_fn.path}", :interactive => true
     unless $?.success?
       info "Error while running gpg: #{message}"
@@ -208,6 +210,23 @@ private
     payload.to_s.gsub(/(^|[^\r])\n/, "\\1\r\n").gsub(/^MIME-Version: .*\r\n/, "")
   end
 
+  # logic is:
+  # if    gpgkey set for this account, then use that
+  # elsif only one account,            then leave blank so gpg default will be user
+  # else                                    set --local-user from_email_address
+  def gen_sign_user_opts from
+    account = AccountManager.account_for from
+    if !account.gpgkey.nil?
+      opts = "--local-user '#{account.gpgkey}'"
+    elsif AccountManager.user_emails.length == 1
+      # only one account
+      opts = ""
+    else
+      opts = "--local-user '#{from}'" 
+    end
+    opts
+  end
+
   def run_gpg args, opts={}
     args = HookManager.run("gpg-args", { :args => args }) || args
     cmd = "LC_MESSAGES=C #{@cmd} #{args}"
-- 
1.7.1

_______________________________________________
Sup-devel mailing list
[email-masked]
http://rubyforge.org/mailman/listinfo/sup-devel

---

From: Rich Lane <[email-masked]>
Date: Mon, 11 Oct 2010 21:38:31 -0400

Applied to master.