benburkert-gpgme 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc ADDED
@@ -0,0 +1,162 @@
1
+ = GPGME
2
+
3
+ This README is better is better viewed through the YARD formatted documentation:
4
+ http://rdoc.info/github/mrsimo/gpgme/master/frames for latest github version, or
5
+ http://rdoc.info/gems/gpgme for latest gem release.
6
+
7
+ == History behind this fork
8
+
9
+ This project started as my Ruby Mendicant University. The idea is to give an
10
+ overhaul to the API of this gem. As a relativelly new developer in the ruby
11
+ world, I found the documentation not very newbie friendly, and the API somewhat
12
+ different to the kind I'm used to in the ruby world.
13
+
14
+ GPG is a very powerful tool, and this gem is implemented using the C bindings,
15
+ making it very fast, and the only proper way to do it.
16
+
17
+ My objectives are as follows:
18
+
19
+ * Add test coverage of some type.
20
+ * Make documentation a little bit more newbie friendly.
21
+ * Improve the API to be more idiomatic.
22
+
23
+ == Requirements
24
+
25
+ * Ruby 1.8 or later
26
+ * GPGME 1.1.2 or later
27
+ * gpg-agent (optional, but recommended)
28
+
29
+ == Installation
30
+
31
+ $ gem install gpgme
32
+
33
+ == API
34
+
35
+ GPGME provides three levels of API. The highest level API is as simple as it
36
+ gets, the mid level API provides more functionality but might be less
37
+ user-friendly, and the lowest level API is close to the C interface of GPGME.
38
+
39
+ === The highest level API
40
+
41
+ For example, to create a cleartext signature of the plaintext from
42
+ stdin and write the result to stdout can be written as follows.
43
+
44
+ crypto = GPGME::Crypto.new
45
+ crypto.clearsign $stdin, :output => $stdout
46
+
47
+ === The mid level API
48
+
49
+ The same example can be rewritten in the mid level API as follows.
50
+
51
+ plain = GPGME::Data.new($stdin)
52
+ sig = GPGME::Data.new($stdout)
53
+ GPGME::Ctx.new do |ctx|
54
+ ctx.sign(plain, sig, GPGME::SIG_MODE_CLEAR)
55
+ end
56
+
57
+ === The lowest level API
58
+
59
+ The same example can be rewritten in the lowest level API as follows.
60
+
61
+ ret = []
62
+ GPGME::gpgme_new(ret)
63
+ ctx = ret.shift
64
+ GPGME::gpgme_data_new_from_fd(ret, 0)
65
+ plain = ret.shift
66
+ GPGME::gpgme_data_new_from_fd(ret, 1)
67
+ sig = ret.shift
68
+ GPGME::gpgme_op_sign(ctx, plain, sig, GPGME::SIG_MODE_CLEAR)
69
+
70
+ As you see, it's much harder to write a program in this API than the
71
+ highest level API. However, if you are already familiar with the C
72
+ interface of GPGME and want to control detailed behavior of GPGME, it
73
+ might be useful.
74
+
75
+ == Usage
76
+
77
+ All the high level methods attack the mid level {GPGME::Ctx} API. It is
78
+ recommended to read through the #{GPGME::Ctx.new} methods for common options.
79
+
80
+ Also, most of the input/output is done via {GPGME::Data} objects that create a
81
+ common interface for reading/writing to normal strings, or other common
82
+ objects like files. Read the {GPGME::Data} documentation to understand
83
+ how it works. Every time the lib needs a {GPGME::Data} object, it will be
84
+ automatically converted to it.
85
+
86
+ === Crypto
87
+
88
+ The {GPGME::Crypto} class has the high level convenience methods to encrypt,
89
+ decrypt, sign and verify signatures. Here are some examples, but it is
90
+ recommended to read through the {GPGME::Crypto} class to see all the options.
91
+
92
+ * Document encryption via {GPGME::Crypto#encrypt}:
93
+ crypto = GPGME::Crypto.new
94
+ crypto.encrypt "Hello world!", :recipients => "someone@example.com"
95
+
96
+ * Symmetric encryption:
97
+ crypto = GPGME::Crypto.new :password => "gpgme"
98
+ crypto.encrypt "Hello world!", :symmetric => true
99
+
100
+
101
+ * Document decryption via {GPGME::Crypto#decrypt} (including signature verification):
102
+ crypto.decrypt File.open("text.gpg")
103
+
104
+ * Document signing via {GPGME::Crypto#sign}. Also the clearsigning and detached signing.
105
+ crypto.sign "I hereby proclaim Github the beneficiary of all my money when I die"
106
+
107
+ * Sign verification via {GPGME::Crypto#verify}
108
+ sign = crypto.sign "Some text"
109
+ data = crypto.verify(sign) { |signature| signature.valid? }
110
+
111
+ === Key
112
+
113
+ The {GPGME::Key} object represents a key, and has the high level related
114
+ methods to work with them and find them, export, import, deletetion and
115
+ creation.
116
+
117
+ * Key listing
118
+ GPGME::Key.find(:secret, "someone@example.com")
119
+ # => Returns an array with all the secret keys available in the keychain.
120
+ # that match "someone@example.com"
121
+
122
+ * Key exporting
123
+ GPGME::Key.export("someone@example.com")
124
+ # => Returns a {GPGME::Data} object with the exported key.
125
+
126
+ key = GPGME::Key.find(:secret, "someone@example.com").first
127
+ key.export
128
+ # => Returns a {GPGME::Data} object with the exported key.
129
+
130
+ * Key importing
131
+ GPGME::Key.import(File.open("my.key"))
132
+
133
+ * TODO: Key generation
134
+
135
+ === Engine
136
+
137
+ Provides three convenience methods to obtain information about the gpg engine
138
+ one is currently using. For example:
139
+
140
+ * Getting current information
141
+ GPGME::Engine.engine_info.first
142
+ # => #<GPGME::EngineInfo:0x00000100d4fbd8
143
+ @file_name="/usr/local/bin/gpg",
144
+ @protocol=0,
145
+ @req_version="1.3.0",
146
+ @version="1.4.11">
147
+
148
+ * Changing home directory to work with different settings:
149
+ GPGME::Engine.home_dir = '/tmp'
150
+
151
+ == Contributing
152
+
153
+ To run the local test suite you need bundler and gpg:
154
+
155
+ bundle
156
+ rake compile # simple rake task to compile the extension
157
+ rake # runs the test suite
158
+
159
+ == License
160
+
161
+ The library itself is licensed under LGPLv2.1+. See the file
162
+ COPYING.LESSER and each file for copyright and warranty information.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ require 'rcov/rcovtask'
6
+ require 'yard'
7
+
8
+
9
+ desc "Re-compile the extensions"
10
+ task :compile do
11
+ FileUtils.rm_rf('tmp') if File.directory?('tmp')
12
+ mkdir 'tmp'
13
+
14
+ Dir.chdir('tmp') do
15
+ system "ruby #{File.dirname(__FILE__)}/ext/gpgme/extconf.rb"
16
+ system "make"
17
+ end
18
+ end
19
+
20
+ task :default => [:test]
21
+
22
+ Rake::TestTask.new(:test => :compile) do |t|
23
+ t.libs << 'test'
24
+ t.pattern = "test/**/*_test.rb"
25
+ t.verbose = true
26
+ end
27
+ Rake::Task['test'].comment = "Run all tests"
28
+
29
+ YARD::Rake::YardocTask.new
30
+
31
+ Rcov::RcovTask.new do |t|
32
+ t.libs << 'test'
33
+ t.pattern = "test/**/*_test.rb"
34
+ t.verbose = true
35
+ t.rcov_opts = ["-x gems"]
36
+ end
37
+
data/THANKS ADDED
@@ -0,0 +1,15 @@
1
+ Ruby-GPGME was originally written by Daiki Ueno. Other people
2
+ contributed by reporting problems, suggesting various improvements or
3
+ submitting actual code. Here is a list of those people. Help us keep
4
+ it complete and free of errors.
5
+
6
+
7
+
8
+ Carl Corliss
9
+ Jérémie Pierson
10
+ Kouhei Sutou
11
+ Kris Nuttycombe
12
+ Marc Dequènes
13
+ Rob Pitt
14
+ Rory McKinley
15
+ Sam Hall
@@ -0,0 +1,30 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'benburkert-gpgme'
3
+ s.version = '0.1.0'
4
+ s.authors = ['Daiki Ueno']
5
+ s.date = '2011-05-09'
6
+ s.email = 'ueno@unixuser.org'
7
+ s.extensions = ['ext/gpgme/extconf.rb']
8
+ s.files = `git ls-files`.split("\n")
9
+ s.has_rdoc = true
10
+ s.rubyforge_project = 'ruby-gpgme'
11
+ s.homepage = 'http://rubyforge.org/projects/ruby-gpgme/'
12
+ s.require_paths = ['lib', 'ext']
13
+ s.summary = "Ben Burkert's fork of the Ruby binding of GPGME."
14
+ s.description = %q{Ruby-GPGME is a Ruby language binding of GPGME (GnuPG
15
+ Made Easy). GnuPG Made Easy (GPGME) is a library designed to make access to
16
+ GnuPG easier for applications. It provides a High-Level Crypto API for
17
+ encryption, decryption, signing, signature verification and key management.}
18
+
19
+ s.add_development_dependency "mocha", "~> 0.9.12"
20
+ s.add_development_dependency "minitest", "~> 2.1.0"
21
+ s.add_development_dependency "yard", "~> 0.6.7"
22
+ s.add_development_dependency "rcov", "~> 0.9.9"
23
+
24
+ case RUBY_VERSION
25
+ when "1.9.2"
26
+ s.add_development_dependency "ruby-debug19" , "~> 0.11.6"
27
+ else
28
+ s.add_development_dependency "ruby-debug" , "~> 0.10.4"
29
+ end
30
+ end
data/examples/edit.rb ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ unless ENV['GNUPGHOME']
28
+ $stderr.write('As GNUPGHOME is not set, the generated key pair will be stored into *your* keyring. Really proceed? (y/N) ')
29
+ $stderr.flush
30
+ exit(1) unless gets.chomp == 'y'
31
+ end
32
+
33
+ unless ARGV.length == 1
34
+ $stderr.puts("Usage: #{$0} KEYGRIP")
35
+ exit(1)
36
+ end
37
+
38
+ def progfunc(hook, what, type, current, total)
39
+ $stderr.write("#{what}: #{current}/#{total}\r")
40
+ $stderr.flush
41
+ end
42
+
43
+ def editfunc(hook, status, args, fd)
44
+ case status
45
+ when GPGME::GPGME_STATUS_GET_BOOL
46
+ begin
47
+ $stderr.write("#{args} (y/n) ")
48
+ $stderr.flush
49
+ line = gets
50
+ end until line =~ /\A\s*[ny]\s*\z/
51
+ io = IO.for_fd(fd)
52
+ io.puts(line.strip)
53
+ io.flush
54
+ when GPGME::GPGME_STATUS_GET_LINE, GPGME::GPGME_STATUS_GET_HIDDEN
55
+ $stderr.write("#{args}: ")
56
+ $stderr.flush
57
+ line = gets
58
+ io = IO.for_fd(fd)
59
+ io.puts(line)
60
+ io.flush
61
+ else
62
+ $stderr.puts([status, args].inspect)
63
+ end
64
+ end
65
+
66
+ ctx = GPGME::Ctx.new({:progress_callback => method(:progfunc),
67
+ # :passphrase_callback => method(:passfunc)
68
+ })
69
+ keystr = ARGV.shift
70
+ keys = ctx.keys(keystr)
71
+ if keys.empty?
72
+ $stderr.puts("Can't find key for \"#{keystr}\"")
73
+ exit(1)
74
+ end
75
+
76
+ $stderr.puts(keys.first.inspect)
77
+ ctx.edit_key(keys.first, method(:editfunc))
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ unless ENV['GNUPGHOME']
28
+ $stderr.write('As GNUPGHOME is not set, the generated key pair will be stored into *your* keyring. Really proceed? (y/N) ')
29
+ $stderr.flush
30
+ exit(1) unless gets.chomp == 'y'
31
+ end
32
+
33
+ def progfunc(hook, what, type, current, total)
34
+ $stderr.write("#{what}: #{current}/#{total}\r")
35
+ $stderr.flush
36
+ end
37
+
38
+ ctx = GPGME::Ctx.new({:progress_callback => method(:progfunc),
39
+ # :passphrase_callback => method(:passfunc)
40
+ })
41
+
42
+ ctx.genkey(<<'EOF', nil, nil)
43
+ <GnupgKeyParms format="internal">
44
+ Key-Type: DSA
45
+ Key-Length: 1024
46
+ Subkey-Type: ELG-E
47
+ Subkey-Length: 1024
48
+ Name-Real: Joe Tester
49
+ Name-Comment: with stupid passphrase
50
+ Name-Email: joe@foo.bar
51
+ Expire-Date: 0
52
+ Passphrase: abc
53
+ </GnupgKeyParms>
54
+ EOF
55
+ $stderr.puts
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ GPGME.list_keys(ARGV.shift) do |key|
5
+ puts(key)
6
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ plain = 'test test test'
28
+ puts("Plaintext:\n#{plain}")
29
+
30
+ # Perform symmetric encryption on PLAIN.
31
+ cipher = GPGME::encrypt(nil, plain, {:armor => true,
32
+ # :passphrase_callback => method(:passfunc)
33
+ })
34
+ puts("Ciphertext:\n#{cipher}")
35
+
36
+ plain = GPGME::decrypt(cipher, {
37
+ # :passphrase_callback => method(:passfunc)
38
+ })
39
+ puts("Plaintext:\n#{plain}")
data/examples/sign.rb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ puts GPGME::clearsign('test test test', {
28
+ # :passphrase_callback => method(:passfunc)
29
+ })
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ GPGME::verify(ARGF.read, nil, $stdout) do |signature|
5
+ puts(signature.to_s)
6
+ end
@@ -0,0 +1,26 @@
1
+ require 'mkmf'
2
+
3
+ unless find_executable('gpgme-config')
4
+ $stderr.puts("gpgme-config not found")
5
+ exit(1)
6
+ end
7
+
8
+ $CFLAGS += ' ' << `gpgme-config --cflags`.chomp
9
+ $libs += ' ' << `gpgme-config --libs`.chomp
10
+
11
+ checking_for('gpgme >= 1.1.3') do
12
+ if try_run(<<'End')
13
+ #include <gpgme.h>
14
+ #include <stdlib.h>
15
+ int main (void) {
16
+ return gpgme_check_version ("1.1.3") == NULL;
17
+ }
18
+ End
19
+ true
20
+ else
21
+ $CFLAGS += ' -DRUBY_GPGME_NEED_WORKAROUND_KEYLIST_NEXT'
22
+ false
23
+ end
24
+ end
25
+ have_func('gpgme_op_export_keys')
26
+ create_makefile ('gpgme_n')