- 0646687DE5D54FD0278B8265786D9E5BB65492DC81F323249B57C129D5293CF605F384B13354379D970AAF04C1757866529320F2B0D8226F64A0F269398DE6CB
+ E983984D664DAEF6D42FD55C86F784BFEAD4057B78673C18A8F8E85346DB539F3F3429DE5185A86805A1E698C2907441B5C2017E224BB1606358B930615CE84C
blatta/lib/infosec.py
(5 . 6)(5 . 8)
96 from lib.serpent import serpent_cbc_decrypt
97 from commands import BROADCAST
98 from commands import DIRECT
99 from commands import IGNORE
100 from lib.message import Message
101 import base64
102 import binascii
103 import time
(12 . 6)(14 . 7)
105 import sys
106 import hmac
107 import random
108 import os
109 import pprint
110 pp = pprint.PrettyPrinter(indent=4)
111
(28 . 6)(31 . 7)
113 DUPLICATE_PACKET = 1
114 MALFORMED_PACKET = 2
115 INVALID_SIGNATURE = 3
116 IGNORED = 4
117
118 class Infosec(object):
119 def __init__(self, server=None):
(35 . 11)(39 . 11)
121
122 def pack(self, peer, message):
123 try:
124 timestamp = message["timestamp"]
125 timestamp = message.timestamp
126 except:
127 timestamp = None
128 command = message["command"]
129 speaker = self._pad(message["speaker"], MAX_SPEAKER_SIZE)
130 command = message.command
131 speaker = self._pad(message.speaker, MAX_SPEAKER_SIZE)
132
133 # if we are rebroadcasting we need to use the original timestamp
134
(56 . 32)(60 . 34)
136 # there this is the first message
137
138
139 if message["original"]:
140 if message.original:
141 if command == DIRECT:
142 self_chain = self.server.state.get_last_message_hash(message["speaker"], peer.peer_id)
143 self_chain = self.server.state.get_last_message_hash(message.speaker, peer.peer_id)
144 elif command == BROADCAST:
145 self_chain = self.server.state.get_last_message_hash(message["speaker"])
146 self_chain = self.server.state.get_last_message_hash(message.speaker)
147 elif command == IGNORE:
148 self_chain = "\x00" * 32
149 net_chain = "\x00" * 32
150 else:
151 self_chain = message["self_chain"]
152 net_chain = message["net_chain"]
153 self_chain = message.self_chain
154 net_chain = message.net_chain
155
156 # pack message bytes
157
158 message_bytes = struct.pack(MESSAGE_PACKET_FORMAT, int_ts, self_chain, net_chain, speaker, message["body"].encode("ascii"))
159 message_bytes = struct.pack(MESSAGE_PACKET_FORMAT, int_ts, self_chain, net_chain, speaker, message.body)
160
161 # log messages
162
163 if message["original"]:
164 if message.original:
165 if command == DIRECT:
166 self.server.state.log(message["speaker"], message_bytes, peer.peer_id)
167 self.server.state.log(message.speaker, message_bytes, peer.peer_id)
168 elif command == BROADCAST:
169 self.server.state.log(message["speaker"], message_bytes)
170 self.server.state.log(message.speaker, message_bytes)
171
172 # pack packet bytes
173
174 nonce = self._generate_nonce(16)
175 bounces = message["bounces"]
176 bounces = message.bounces
177 version = 0xfe
178 red_packet_bytes = struct.pack(RED_PACKET_FORMAT, nonce, bounces, version, command, self._pad(message_bytes, MAX_MESSAGE_LENGTH))
179
(114 . 14)(120 . 14)
181 black_packet_bytes, signature_bytes = struct.unpack(BLACK_PACKET_FORMAT, black_packet)
182 except:
183 self.server.print_error("Discarding malformed black packet from %s" % peer.get_key())
184 return { "error_code": MALFORMED_PACKET }
185 return Message({ "error_code": MALFORMED_PACKET }, self.server)
186
187 # check signature
188
189 signature_check_bytes = hmac.new(signing_key, black_packet_bytes, hashlib.sha384).digest()
190
191 if(signature_check_bytes != signature_bytes):
192 return { "error_code": INVALID_SIGNATURE }
193 return Message({ "error_code": INVALID_SIGNATURE }, self.server)
194
195 # try to decrypt black packet
196
(132 . 6)(138 . 11)
198
199 nonce, bounces, version, command, message_bytes = struct.unpack(RED_PACKET_FORMAT, red_packet_bytes)
200
201 # nothing to be done for an IGNORE command
202
203 if command == IGNORE:
204 return Message({"error_code": IGNORED})
205
206 # unpack message
207
208 int_ts, self_chain, net_chain, speaker, message = struct.unpack(MESSAGE_PACKET_FORMAT, message_bytes)
(140 . 10)(151 . 10)
210 # check timestamp
211
212 if(int_ts not in self._ts_range()):
213 return { "error_code": STALE_PACKET }
214 return Message({ "error_code": STALE_PACKET }, self.server)
215
216 if(self.server.recent.has(int_ts)):
217 return { "error_code": DUPLICATE_PACKET }
218 return Message({ "error_code": DUPLICATE_PACKET }, self.server)
219 else:
220 self.server.recent.insert(int_ts)
221
(167 . 17)(178 . 19)
223 unpadded_message = message[0:index]
224 break
225
226 # return the message, timestamp, and command (command replaces propagate)
227
228 return { "body": unpadded_message.rstrip(),
229 "timestamp": int_ts,
230 "command": command,
231 "speaker": speaker,
232 "bounces": bounces,
233 "self_chain": self_chain,
234 "net_chain": net_chain,
235 "self_chain_valid": self_chain_valid,
236 "error_code": None}
237 return Message({
238 "peer": peer,
239 "body": unpadded_message.rstrip(),
240 "timestamp": int_ts,
241 "command": command,
242 "speaker": speaker,
243 "bounces": bounces,
244 "self_chain": self_chain,
245 "net_chain": net_chain,
246 "self_chain_valid": self_chain_valid,
247 "error_code": None
248 },
249 self.server)
250
251 def _pad(self, text, size):
252 return text.ljust(size)
(189 . 3)(202 . 6)
254 def _generate_nonce(self, length=8):
255 """Generate pseudorandom number."""
256 return ''.join([str(random.randint(0, 9)) for i in range(length)])
257
258 def gen_rubbish_body(self):
259 return os.urandom(MAX_MESSAGE_LENGTH)