#!/usr/bin/env ruby # KeyRub! # Key-signing utility # provide the short hex of a GPG key, and KeyRub will get # the full key from the server, show you the fingerprint, # let you sign the key, then send out an encrypted mail # containing the newly-signed key. The recipient simply has # to "gpg import" the decrypted mail and then pop your # key up to the server. # # If you are using a Ruby version >= 1.9, you can remove # the Net::SMTP monkeypatch, as you can if you are using # an SMTP provider who does not use STARTTLS. # # The TLS monkeypatch is taken from the listed URIs # All the code which I wrote is # Copyright (c) Tom Morris 2008. # but is available under the GNU General Public License. # Please send me modifications by e-mail. require 'openssl' require 'net/smtp' require 'facets' # Net::SMTP TLS monkeypatching # from http://artima.com/forums/flat.jsp?forum=123&thread=221075 # from http://d.hatena.ne.jp/zorio/20060416 Net::SMTP.class_eval do private def do_start(helodomain, user, secret, authtype) raise IOError, 'SMTP session already started' if @started check_auth_args user, secret, authtype if user or secret sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) } @socket = Net::InternetMessageIO.new(sock) @socket.read_timeout = 60 #@read_timeout @socket.debug_output = STDERR #@debug_output check_response(critical { recv_response() }) do_helo(helodomain) raise 'openssl library not installed' unless defined?(OpenSSL) starttls ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.sync_close = true ssl.connect @socket = Net::InternetMessageIO.new(ssl) @socket.read_timeout = 60 #@read_timeout @socket.debug_output = STDERR #@debug_output do_helo(helodomain) authenticate user, secret, authtype if user @started = true ensure unless @started # authentication failed, cancel connection. @socket.close if not @started and @socket and not @socket.closed? @socket = nil end end def do_helo(helodomain) begin if @esmtp ehlo helodomain else helo helodomain end rescue Net::ProtocolError if @esmtp @esmtp = false @error_occured = false retry end raise end end def starttls getok('STARTTLS') end end #hex = ARGV[0].to_s silence_stream(STDOUT) do passwordstr = `security 2>&1 >/dev/null find-internet-password -g -s "smtp.gmail.com"` password = passwordstr.scan(/^password: "(.*)"$/)[0].to_s if password.length != 0 exit end smtp = Net::SMTP.new('smtp.gmail.com', 587) smtp.start(nil, 'bbtommorris@gmail.com', password, :login) end ARGV.each { |h| hex = h.to_s.strip system "gpg --recv-keys " + hex system "gpg --fingerprint " + hex puts "Enter your passphrase to sign the key and copy the ASCII-armoured key to your pasteboard, or Ctrl-C if you decide you don't want to sign this key." if system("gpg --sign-key " + hex) != false keystr = `gpg --fingerprint #{hex}` keystr.scan(/\<(\S*@\S*)>/).each do |uid| uid2 = uid.to_s ascii_key = `gpg -a --export #{uid2} | gpg -a --encrypt -r #{uid2}` msg = "From: Tom Morris \n" msg += "To: " + uid2 + "\n" msg += "Subject: GPG Signed Key " + hex + "\n\n" msg += ascii_key silence_stream(STDOUT) do smtp.send_message msg, "tom@tommorris.org", uid2 end puts "Signed key sent to " + uid2 + "\n" end end } smtp.finish