Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GPGME::Crypto#encrypt throws an Errno::EBADF exception #54

Open
vakuum opened this issue Oct 17, 2014 · 2 comments
Open

GPGME::Crypto#encrypt throws an Errno::EBADF exception #54

vakuum opened this issue Oct 17, 2014 · 2 comments

Comments

@vakuum
Copy link

vakuum commented Oct 17, 2014

The following code always throws an Errno::EBADF exception after some loop iterations:

require 'gpgme'

puts GPGME::Engine.info.inspect

crypto = GPGME::Crypto.new(armor: false, symmetric: true, password: 'password')

(0..1000000).each do |n|
  puts n
  crypto.encrypt(GPGME::Data.from_str('data'))
end

I tried it with Ruby 2.0.0p353 and Ruby 2.0.0p576 on Ubuntu 12.04.5 LTS and Ubuntu 14.04.1 LTS:

$ rvm use ruby-2.0.0-p576@gpgme --create

$ gem install gpgme
...
Successfully installed mini_portile-0.6.0
...
Successfully installed gpgme-2.0.7
...

$ ruby test.rb
[#<GPGME::EngineInfo:0x000000014bda10 @protocol=0, @file_name="/usr/bin/gpg", @version="1.4.16", @req_version="1.4.0">, #<GPGME::EngineInfo:0x000000014bd970 @protocol=6, @file_name="/nonexistent", @version="1.0", @req_version="1.0">]
0
1
...
403
404
/home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:484:in `flush': Bad file descriptor (Errno::EBADF)
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:484:in `pass_function'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:449:in `call'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:449:in `gpgme_op_encrypt'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:449:in `encrypt'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/crypto.rb:99:in `block in encrypt'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/ctx.rb:71:in `new'
        from /home/clemens/.rvm/gems/ruby-2.0.0-p576@gpgme/gems/gpgme-2.0.7/lib/gpgme/crypto.rb:90:in `encrypt'
        from test.rb:21:in `block in <main>'
        from test.rb:19:in `each'
        from test.rb:19:in `<main>'

Installed packages under Ubuntu 12.04.5 LTS

$ dpkg --list gnupg libgpgme11 libgpgme11-dev
...
ii  gnupg                         1.4.11-3ubuntu2.7             GNU privacy guard - a free PGP replacement
ii  libgpgme11                    1.2.0-1.4ubuntu2.1            GPGME - GnuPG Made Easy
ii  libgpgme11-dev                1.2.0-1.4ubuntu2.1            GPGME - GnuPG Made Easy

Installed packages under Ubuntu 14.04.1 LTS

$ dpkg --list gnupg libgpgme11 libgpgme11-dev
...
ii  gnupg                         1.4.16-1ubuntu2.1   amd64               GNU privacy guard - a free PGP replacement
ii  libgpgme11:amd64              1.4.3-0.1ubuntu5.1  amd64               GPGME - GnuPG Made Easy (library)
ii  libgpgme11-dev                1.4.3-0.1ubuntu5.1  amd64               GPGME - GnuPG Made Easy (development files)
@ueno
Copy link
Owner

ueno commented Oct 22, 2014

I'm still looking for a proper way to fix this, but for your use-case, a workaround would be to use a custom passphrase callback and call IO#close at the end:

def pass_function(pass, uid_hint, passphrase_info, prev_was_bad, fd)
  io = IO.for_fd(fd, 'w')
  io.puts 'password'
  io.flush
  io.close
end

crypto = GPGME::Crypto.new(armor: false, symmetric: true,
                           passphrase_callback: method(:pass_function))

However, I doubt that we can simply do that in our default callback, as other gpgme engines might assume the FD is never closed.

@vakuum
Copy link
Author

vakuum commented Oct 22, 2014

Closing the file handle in the passphrase callback solved the problem.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants