commit f31d1e5c31f69722fc530b1354952a1909ee778e
parent ef0408c88306fb75b7dc987d6ec6560f3573b380
Author: Clint Byrum <clint@ubuntu.com>
Date: Thu, 17 Nov 2011 00:14:56 -0800
all tests pass on gpgme 1.0.7 and 2.0.0
Diffstat:
2 files changed, 62 insertions(+), 15 deletions(-)
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
@@ -64,10 +64,17 @@ EOS
@gpgme_present =
begin
begin
- GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
+ begin
+ GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
+ rescue TypeError
+ GPGME.check_version(nil)
+ end
true
rescue GPGME::Error
false
+ rescue ArgumentError
+ # gpgme 2.0.0 raises this due to the hash->string conversion
+ false
end
rescue NameError
false
@@ -81,7 +88,11 @@ EOS
# if gpg2 is available, it will start gpg-agent if required
if (bin = `which gpg2`.chomp) =~ /\S/
- GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
+ if GPGME.respond_to?('set_engine_info')
+ GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
+ else
+ GPGME.gpgme_set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
+ end
else
# check if the gpg-options hook uses the passphrase_callback
# if it doesn't then check if gpg agent is present
@@ -120,14 +131,20 @@ EOS
{:operation => "sign", :options => gpg_opts}) || gpg_opts
begin
- sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
+ if GPGME.respond_to?('detach_sign')
+ sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
+ else
+ crypto = GPGME::Crypto.new
+ gpg_opts[:mode] = GPGME::SIG_MODE_DETACH
+ crypto.sign(format_payload(payload), gpg_opts)
+ end
rescue GPGME::Error => exc
raise Error, gpgme_exc_msg(exc.message)
end
# if the key (or gpg-agent) is not available GPGME does not complain
# but just returns a zero length string. Let's catch that
- if sig.length == 0
+ if sig.respond_to?('length') && sig.length == 0
raise Error, gpgme_exc_msg("GPG failed to generate signature: check that gpg-agent is running and your key is available.")
end
@@ -153,14 +170,20 @@ EOS
recipients = to + [from]
recipients = HookManager.run("gpg-expand-keys", { :recipients => recipients }) || recipients
begin
- cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
+ if GPGME.respond_to?('encrypt')
+ cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
+ else
+ crypto = GPGME::Crypto.new
+ gpg_opts[:recipients] = recipients
+ cipher = crypto.encrypt(format_payload(payload), gpg_opts).read
+ end
rescue GPGME::Error => exc
raise Error, gpgme_exc_msg(exc.message)
end
# if the key (or gpg-agent) is not available GPGME does not complain
# but just returns a zero length string. Let's catch that
- if cipher.length == 0
+ if cipher.respond_to?('length') && !cipher.length == 0
raise Error, gpgme_exc_msg("GPG failed to generate cipher text: check that gpg-agent is running and your key is available.")
end
@@ -262,7 +285,11 @@ EOS
{:operation => "decrypt", :options => gpg_opts}) || gpg_opts
ctx = GPGME::Ctx.new(gpg_opts)
cipher_data = GPGME::Data.from_str(format_payload(payload))
- plain_data = GPGME::Data.empty
+ if GPGME::Data.respond_to?('empty')
+ plain_data = GPGME::Data.empty
+ else
+ plain_data = GPGME::Data.empty!
+ end
begin
ctx.decrypt_verify(cipher_data, plain_data)
rescue GPGME::Error => exc
@@ -330,7 +357,7 @@ private
def gpgme_exc_msg msg
err_msg = "Exception in GPGME call: #{msg}"
- info err_msg
+ #info err_msg
err_msg
end
diff --git a/test/test_crypto.rb b/test/test_crypto.rb
@@ -22,11 +22,13 @@
require 'tmpdir'
require 'test/unit'
require 'rmail/message'
+require 'rmail/parser'
require 'sup/util'
require 'sup/hook'
require 'sup/contact'
require 'sup/person'
require 'sup/account'
+require 'sup/message-chunks'
require 'sup/crypto'
require 'stringio'
@@ -37,13 +39,15 @@ CryptoManager.init
Dir.mktmpdir('sup-test') do|f|
HookManager.init f
end
-am = {:default=> {:name => "bob", :email=>"bob@foo.nowhere"}}
+am = {:default=> {:name => "", :email=>ENV['EMAIL']}}
AccountManager.init am
-print CryptoManager.have_crypto?
class TestCryptoManager < Test::Unit::TestCase
def setup
+ @from_email = ENV['EMAIL']
+ # Change this or import my public key to make these tests work.
+ @to_email = 'clint@ubuntu.com'
end
def teardown
@@ -51,22 +55,38 @@ class TestCryptoManager < Test::Unit::TestCase
def test_sign
if CryptoManager.have_crypto? then
- signed = CryptoManager.sign "bob@foo.nowhere","alice@bar.anywhere","ABCDEFG"
+ signed = CryptoManager.sign @from_email,@to_email,"ABCDEFG"
assert_instance_of RMail::Message, signed
end
end
-
def test_encrypt
if CryptoManager.have_crypto? then
- from_email = Person.from_address("bob@foo.nowhere").email
- to_email = Person.from_address("alice@bar.anywhere").email
+ encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ end
+ end
- encrypted = CryptoManager.encrypt from_email, [to_email], "ABCDEFG"
+ def test_sign_and_encrypt
+ if CryptoManager.have_crypto? then
+ encrypted = CryptoManager.sign_and_encrypt @from_email, [@to_email], "ABCDEFG"
assert_instance_of RMail::Message, encrypted
end
end
+ def test_decrypt
+ if CryptoManager.have_crypto? then
+ encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
+ assert_instance_of RMail::Message, encrypted
+ assert_instance_of String, (encrypted.body[1].body)
+ decrypted = CryptoManager.decrypt encrypted.body[1], true
+ assert_instance_of Array, decrypted
+ assert_instance_of Chunk::CryptoNotice, decrypted[0]
+ assert_instance_of Chunk::CryptoNotice, decrypted[1]
+ assert_instance_of RMail::Message, decrypted[2]
+ assert_equal "ABCDEFG" , decrypted[2].body
+ end
+ end
end