Class: CARPS::Mailer

Inherits:
Object
  • Object
show all
Defined in:
lib/carps/crypt/mailer.rb

Overview

High level CARPS mail client supporting strong cryptographic message signing.

It has knowledge of our own public and private key. Its big responsibility is turning Messages into Strings and signing them.

Instance Method Summary collapse

Constructor Details

#initialize(address, mailbox) ⇒ Mailer

The first parameter is the email address

The second the Mailbox.



49
50
51
52
53
54
55
56
# File 'lib/carps/crypt/mailer.rb', line 49

def initialize address, mailbox
   @addr = address
   @mailbox = mailbox
   @private_key = get_keys
   @public_key = @private_key.public_key
   # Load the old peers
   load_peers
end

Instance Method Details

#addressObject

Give our address to interested parties



119
120
121
# File 'lib/carps/crypt/mailer.rb', line 119

def address
   @addr
end

#check(type, must_be_from = nil) ⇒ Object

Check for a message. Don’t block! Return nil if nothing is available.



142
143
144
# File 'lib/carps/crypt/mailer.rb', line 142

def check type, must_be_from=nil
   @mailbox.check type, must_be_from
end

#check_handshakeObject

Check for handshakes



87
88
89
# File 'lib/carps/crypt/mailer.rb', line 87

def check_handshake
   @mailbox.insecure_check Handshake
end

#handle_handshake(handshake) ⇒ Object

Respond to a handshake request



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/carps/crypt/mailer.rb', line 92

def handle_handshake handshake
   # Get the peer's address
   from = handshake.from
   puts "Receiving handshake request from #{from}."
   if @mailbox.peer? from
      UI::warn "Handshake request from #{from} has been dropped because #{from} is already a known peer",  "Possible spoofing attack."
   else
      # See if the user accepts the handshake.
      accept = accept_handshake? from
      if accept
         # Send our key to the peer
         send from, PublicKey.new(@public_key)
         # Get their key
         peer_key = @mailbox.insecure_read PublicKey, from
         # Create a new peer
         peer = Peer.new from
         @mailbox.add_peer peer
         peer.your_key peer_key.key
         peer.save
         # Send an okay message
         send from, AcceptHandshake.new
         puts "Established spoof-proof communications with #{from}."
      end
   end
end

#handshake(to) ⇒ Object

Perform a handshake to authenticate with a peer



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/carps/crypt/mailer.rb', line 59

def handshake to
   if @mailbox.peer? to
      puts "No need for handshake: " + to + " is already a known peer."
   else
      puts "Offering cryptographic handshake to #{to}"
      # Create a new peer
      peer = Peer.new to
      @mailbox.add_peer peer
      # Request a handshake 
      send to, Handshake.new
      # Get the peer's key
      their_key = @mailbox.insecure_read PublicKey, to
      peer.your_key their_key.key
      peer.save 
      # Send our key
      send to, PublicKey.new(@public_key)
      # Receive an okay message
      read AcceptHandshake, to
      puts "Established spoof-proof communications with #{to}"
   end
end

#read(type, must_be_from = nil) ⇒ Object

Receive a message. Block until it is here.



137
138
139
# File 'lib/carps/crypt/mailer.rb', line 137

def read type, must_be_from=nil
   @mailbox.read type, must_be_from
end

#send(to, message) ⇒ Object

Send a message



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/carps/crypt/mailer.rb', line 124

def send to, message
   text = message.emit
   # The mailbox tags the message with a session key
   text = @mailbox.tag text
   # Sign the message
   digest = Digest::MD5.digest text
   sig = @private_key.syssign digest
   mail = (V.addr @addr) + (V.sig sig) + text + K.end
   @mailbox.send to, mail
   puts "#{message.class} sent to " + to
end

#shutdownObject

Shutdown the mailer



82
83
84
# File 'lib/carps/crypt/mailer.rb', line 82

def shutdown
   @mailbox.shutdown
end