Class: Redwood::CryptoManager

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/sup/crypto.rb

Instance Method Summary collapse

Constructor Details

#initializeCryptoManager

Returns a new instance of CryptoManager.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/sup/crypto.rb', line 6

def initialize
  @mutex = Mutex.new
  self.class.i_am_the_instance self

  bin = `which gpg`.chomp
  bin = `which pgp`.chomp unless bin =~ /\S/

  @cmd =
    case bin
    when /\S/
      "#{bin} --quiet --batch --no-verbose --logger-fd 1 --use-agent"
    else
      nil
    end
end

Instance Method Details

#decrypt(payload) ⇒ Object

returns decrypted_message, status, desc, lines



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/sup/crypto.rb', line 53

def decrypt payload # RubyMail::Message objects
  return unknown_status(cant_find_binary) unless @cmd

#    cmd = "#{@cmd} --decrypt 2> /dev/null"

#    Redwood::log "gpg: running: #{cmd}"

#    gpg_output =
#      IO.popen(cmd, "a+") do |f|
#        f.puts payload.to_s
#        f.gets
#      end

  payload_fn = Tempfile.new "redwood.payload"
  payload_fn.write payload.to_s
  payload_fn.close

  cmd = "#{@cmd} --decrypt #{payload_fn.path} 2> /dev/null"
  Redwood::log "gpg: running: #{cmd}"
  gpg_output = `#{cmd}`
  Redwood::log "got output: #{gpg_output.inspect}"

  if $? == 0 # successful decryption
    decrypted_payload, sig_lines =
      if gpg_output =~ /\A(.*?)((^gpg: .*$)+)\Z/m
        [$1, $2]
      else
        [gpg_output, nil]
      end
    
    sig = 
      if sig_lines # encrypted & signed
        if sig_lines =~ /^gpg: (Good signature from .*$)/
          Chunk::CryptoNotice.new :valid, $1, sig_lines.split("\n")
        else
          Chunk::CryptoNotice.new :invalid, $1, sig_lines.split("\n")
        end
      end

    notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display"
    [RMail::Parser.read(decrypted_payload), sig, notice]
  else
    notice = Chunk::CryptoNotice.new :invalid, "This message could not be decrypted", gpg_output.split("\n")
    [nil, nil, notice]
  end
end

#verify(payload, signature) ⇒ Object

returns a cryptosignature



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/sup/crypto.rb', line 23

def verify payload, signature # both RubyMail::Message objects
  return unknown_status(cant_find_binary) unless @cmd

  payload_fn = Tempfile.new "redwood.payload"
  payload_fn.write payload.to_s.gsub(/(^|[^\r])\n/, "\\1\r\n").gsub(/^MIME-Version: .*\r\n/, "")
  payload_fn.close

  signature_fn = Tempfile.new "redwood.signature"
  signature_fn.write signature.decode
  signature_fn.close

  cmd = "#{@cmd} --verify #{signature_fn.path} #{payload_fn.path} 2> /dev/null"

  #Redwood::log "gpg: running: #{cmd}"
  gpg_output = `#{cmd}`
  #Redwood::log "got output: #{gpg_output.inspect}"
  output_lines = gpg_output.split(/\n/)

  if gpg_output =~ /^gpg: (.* signature from .*$)/
    if $? == 0
      Chunk::CryptoNotice.new :valid, $1, output_lines
    else
      Chunk::CryptoNotice.new :invalid, $1, output_lines
    end
  else
    unknown_status output_lines
  end
end