8 self.class.i_am_the_instance self
10 bin = `which gpg`.chomp
11 bin = `which pgp`.chomp unless bin =~ /\S/
16 "#{bin} --quiet --batch --no-verbose --logger-fd 1 --use-agent"
22 # returns a cryptosignature
23 def verify payload, signature # both RubyMail::Message objects
24 return unknown_status(cant_find_binary) unless @cmd
26 payload_fn = Tempfile.new "redwood.payload"
27 payload_fn.write payload.to_s.gsub(/(^|[^\r])\n/, "\\1\r\n").gsub(/^MIME-Version: .*\r\n/, "")
30 signature_fn = Tempfile.new "redwood.signature"
31 signature_fn.write signature.decode
34 cmd = "#{@cmd} --verify #{signature_fn.path} #{payload_fn.path} 2> /dev/null"
36 #Redwood::log "gpg: running: #{cmd}"
38 #Redwood::log "got output: #{gpg_output.inspect}"
39 output_lines = gpg_output.split(/\n/)
41 if gpg_output =~ /^gpg: (.* signature from .*$)/
43 Chunk::CryptoNotice.new :valid, $1, output_lines
45 Chunk::CryptoNotice.new :invalid, $1, output_lines
48 unknown_status output_lines
52 # returns decrypted_message, status, desc, lines
53 def decrypt payload # RubyMail::Message objects
54 return unknown_status(cant_find_binary) unless @cmd
56 # cmd = "#{@cmd} --decrypt 2> /dev/null"
58 # Redwood::log "gpg: running: #{cmd}"
61 # IO.popen(cmd, "a+") do |f|
66 payload_fn = Tempfile.new "redwood.payload"
67 payload_fn.write payload.to_s
70 cmd = "#{@cmd} --decrypt #{payload_fn.path} 2> /dev/null"
71 Redwood::log "gpg: running: #{cmd}"
73 Redwood::log "got output: #{gpg_output.inspect}"
75 if $? == 0 # successful decryption
76 decrypted_payload, sig_lines =
77 if gpg_output =~ /\A(.*?)((^gpg: .*$)+)\Z/m
84 if sig_lines # encrypted & signed
85 if sig_lines =~ /^gpg: (Good signature from .*$)/
86 Chunk::CryptoNotice.new :valid, $1, sig_lines.split("\n")
88 Chunk::CryptoNotice.new :invalid, $1, sig_lines.split("\n")
92 notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display"
93 [RMail::Parser.read(decrypted_payload), sig, notice]
95 notice = Chunk::CryptoNotice.new :invalid, "This message could not be decrypted", gpg_output.split("\n")
102 def unknown_status lines=[]
103 Chunk::CryptoNotice.new :unknown, "Unable to determine validity of cryptographic signature", lines
107 ["Can't find gpg or pgp binary in path"]