grant-olson / rubygems-openpgp

This allows you to cryptographically sign ruby gems, so that a user can later verify that they've downloaded a copy that hasn't been tampered with or hacked.
http://www.rubygems-openpgp-ca.org
Other
32 stars 4 forks source link

Automatic Gem Verification #7

Closed yorickpeterse closed 11 years ago

yorickpeterse commented 11 years ago

Note that this is still a work in progress. Right now the output is a bit too verbose, especially since most of the Gems available today won't be signed using OpenPGP (at least for the time being).

yorickpeterse commented 11 years ago

I'm leaving the output as it is. Automatic verification seems to work fine although I haven't been able to install a hijacked Gem yet (probably doing something wrong with creating a proper tarball).

grant-olson commented 11 years ago

Thanks. I appreciate this. It does make things much less clunky.

In the future, please don't reformat code in a pull request. It makes it much more difficult to read the diff. I would prefer a separate pull request for items like this.

Also, be forewarned, I haven't touched the code in 18 months, so I might ask some questions that I should really know the answer to.

I haven't had a chance to test this yet. Two questions I might as well ask now since I might not get to testing until the weekend.

  1. What happens when I grab a gem that hasn't been signed?
  2. What happens if I build a gem when I don't have a signing key? Does it blow up?

I guess now I'm wondering if the key should be explicitly specified in the gemspec file.

I'm also thinking, at least for now, the default behavior should be to act as normal rubygems, unless a flag is provided in the 'gem build' or 'gem install' commands, or setup as an overriding default in .gemrc.

Do you know how easy or hard it is to add these flags in plugin form? Is it possible?

Thanks again for the pull request.

grant-olson commented 11 years ago

IT looks like maybe Gem::Command.add_common_option would work?

If that does, I'd prefer to have --sign and --verify be explicit flags to the standard commands that, for now, are explicitly required. Once more signed gems are around, I'd be up for flipping behavior to a default sign and verify, with explicit --no-verify and --no-sign.

Also, does the --key option work with the new auto-signing config?

grant-olson commented 11 years ago

Actually, it looks like we can add this in lib/rubygems_plugin.rb:

Gem::CommandManager.instance[:install].add_option("--foobar", "baz") do
end

I think we should try to use this to add the options, and also get rid of the sign and verify commands.

I want to do some serious refactoring here, so I"m going to write the code myself.

Still, I greatly appreciate your pull request, I never would have figured this out without it. I'll add your name to the CONTRIBS file for the both inspiration and hook code you provided

yorickpeterse commented 11 years ago

When you try to install a Gem that hasn't been signed it will currently emit a warning but continue the process. You can also build a Gem without signing it just fine since I'm not hooking into that part. If I were it would most likely affect every single Gem you'd try to build since hooks don't have any context attached to them.

I'm also thinking, at least for now, the default behavior should be to act as normal rubygems, unless a flag is provided in the 'gem build' or 'gem install' commands, or setup as an overriding default in .gemrc.

Agreed, I myself would probably be very annoyed the moment I try to install 20 Gems (e.g. a Gem with some dependencies) and then get the same warning 20 times. As far as I know these options and such can be added using the command/plugin API. However, I've only barely scratched the surface of RubyGems plugins so I don't know too much about this area.

Also, does the --key option work with the new auto-signing config?

In the way it currently is it probably doesn't since the hook is executed in the context of the Gem installer command which doesn't have this option.

Looking at the code however I think it might not be such a bad idea to pull things a part a bit and refactor it so that at least the GPG part can be re-used without it loading everything related to RubyGems. I already went a bit overboard with this sadly as you noticed yourself. When thinking of this I think we'd have to do something along the lines of the following:

Seeing how @postmodern asked if it was possible for him to use this code for signing files in Rake tasks I think the first item is especially worth considering. Allow people to do the following would be pretty sweet:

key    = OpenPGP::Key.open('123abc')
digest = OpenPGP::Digest.new(key)

digest.hexdigest('content of a file or something along those lines')

In an ideal world the whole thing wouldn't use a shell at all but sadly I don't see myself having the time to implement PGP in pure Ruby any time soon. It can certainly be done (e.g. there's a pure Perl implementation) but it will most likely take at least several months for it to reach a state where it becomes usable.

yorickpeterse commented 11 years ago

On second thought, and maybe I'm just rambling here (it's getting quite late): if we're going down the route of "Screw cross-platform compatibility!" I might as well see if I can write a proper binding for GPGME (or fix the existing one). It would probably require considerably less time than doing it all in pure Ruby. Then again it would also make maintaining it in the long run harder since fewer Ruby developers are comfortable with dealing with C code [1].

[1]: FFI is something I don't really consider an option for things like these since it's just so slow as balls and felt very fragile the last time I used it.

postmodern commented 11 years ago

@YorickPeterse I say we attempt to write FFI bindings. FFI 1.x has stabilized and is pretty fast on 1.9. On JRuby it drops right down to JFFI. Rubinius is still fixing up their underlying FFI implementation.

postmodern commented 11 years ago

It appears someone has already written C extensions for gpgme. Although, I know how easy it is to create vulnerabilities in C (memory corruption, integer overflows, implicit type promotions). I would trust FFI bindings more; or audit the C extensions.

grant-olson commented 11 years ago

This is getting a little off-topic for the pull request topic...

At this point please don't write any patches replacing the back-end yet. Writing a major patch like that at this point is just bound to cause problems.

What I'd like to do for the next release (0.3.0) is focus on removing the current clunking interface and provide something that's more usable, rather than spend days and weeks re-writing a back end that works. I've opened issues #9 and #10 and will work on them when I can.

If either of you wants to give it a try though, just make a note in the issue so we don't step on each other's toes.

Also please open specific issues to discuss a new back end, etc.

postmodern commented 11 years ago

@YorickPeterse let's move our plotting to IRC.

grant-olson commented 11 years ago

You can now specify --verify in the gem install command. This can be added to ~/.gemrc if you want it to be default behavior.

I did the refactoring I needed to implement issue #9, but thanks for the pull request. That sent me down the right trail.